package org.linlinjava.litemall.web.service;

import static org.linlinjava.litemall.core.exception.util.ServiceExceptionUtil.exception;
import static org.linlinjava.litemall.db.beans.Constants.*;
import static org.linlinjava.litemall.web.ErrorCodeConstants.LUMIERE_ORDER_GOODS_IS_NULL;
import static org.linlinjava.litemall.web.ErrorCodeConstants.LUMIERE_PACKAGE_IS_NULL;
import static org.linlinjava.litemall.web.util.WebResponseCode.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Editor;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.linlinjava.litemall.core.exception.BusinessRuntimeException;
import org.linlinjava.litemall.core.notify.NoticeHelper;
import org.linlinjava.litemall.core.notify.netty.PushService;
import org.linlinjava.litemall.core.payment.DefaultCurType;
import org.linlinjava.litemall.core.payment.paypal.service.impl.GoodsPaypalServiceImpl;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.ResponseUtil.Response;
import org.linlinjava.litemall.db.beans.Constants;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.dto.LitemallAccountBookFormDto;
import org.linlinjava.litemall.db.dto.WebOrderGoodsRemarkDTO;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.PageTools;
import org.linlinjava.litemall.web.ErrorCodeConstants;
import org.linlinjava.litemall.web.dto.*;
import org.linlinjava.litemall.web.vo.*;
import org.linlinjava.litemall.web.vo.cook.UpdateCookReqVO;
import org.linlinjava.litemall.web.vo.order.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

/**
 * 订单服务
 */
@Service
@Slf4j
@Transactional
public class WebOrderGoodsService {

	@Autowired
	private LitemallOrderService orderService;




	@Autowired
	private LumiereCouponUserService lumiereCouponUserService;

	/**
	 * 订单商品服务
	 */
	@Autowired
	private WebOrderGoodsService webOrderGoodsService;

	@Autowired
	private LitemallOrderGoodsService orderGoodsService;
	@Autowired
	private LitemallOrderRecordService orderRecordService;
	@Autowired
	private LitemallGoodsService goodsService;
	@Autowired
	private LitemallShopRegionService shopRegionService;
	@Autowired
	private LitemallRegionService regionService;
	@Autowired
	private LitemallGoodsSpecificationService goodsSpecificationService;
	@Autowired
	private LitemallTaxService litemallTaxService;
	@Autowired
	private LitemallOrderTaxService litemallOrderTaxService;
	@Autowired
	private LitemallGoodsAccessoryService litemallGoodsAccessoryService;
	@Autowired
	private LitemallOrderGoodsAccessoryService litemallOrderGoodsAccessoryService;
	@Autowired
	private LitemallGoodsRegionService goodsRegionService;
	@Autowired
	private WebOrderService webOrderService;
	@Autowired
	private LitemallGoodsSpecificationMerchandiseService goodsSpecificationMerchandiseService;
	@Autowired
	private LitemallShopMerchandiseService litemallShopMerchandiseService;
	@Autowired
	private LitemallOrderGoodsPropertyService litemallOrderGoodsPropertyService;
	@Autowired
	private LitemallMerchandiseService litemallMerchandiseService;
	@Autowired
	private LitemallGoodsSpecificationService specService;
	@Autowired
	private LitemallGoodsSpecificationMerchandiseService specMerchandiseService;
	@Autowired
	private LitemallGoodsPropertyService goodsPropertyService;
	@Autowired
	private LitemallGoodsAccessoryService accessoryService;
	@Autowired
	private LitemallGoodsAccessoryGroupService goodsAccessoryGroupService;
	@Autowired
	private PushService pushService;
	@Autowired
	private NoticeHelper noticeHelper;
	@Autowired
	private LitemallGoodsSpecificationService litemallGoodsSpecificationService;
	@Autowired
	private LitemallUserService userService;

	@Autowired
	private LitemallRechargeConsumptionService litemallRechargeConsumptionService;
	@Autowired
	private GoodsPaypalServiceImpl paypalService;
	@Autowired
	private LitemallOrderCashService litemallOrderCashService;
	@Autowired
	private LitemallCashScheduleService litemallCashScheduleService;

	@Autowired
	private LitemallAccountBookService litemallAccountBookService;

	@Autowired
	private LitemallGiftCardUserService litemallGiftCardUserService;

	@Autowired
	private LitemallGiftCardUserLogService litemallGiftCardUserLogService;

	@Autowired
	private LumiereCloverPayLogService lumiereCloverPayLogService;
	@Autowired
	private LitemallGoodsSpecificationMerchandiseService litemallGoodsSpecificationMerchandiseService;

	@Autowired
	private LitemallOrderFormulaMaterialService litemallOrderFormulaMaterialService;


	@Autowired
	private LumiereFormulaSpecificationsService lumiereFormulaSpecificationsService;

	@Autowired
	private LumierePackageService lumierePackageService;

	@Autowired
	private LitemallOrderPackageService litemallOrderPackageService;

	@Autowired
	private LumiereFormulaSpecificationsDataProportioningService lumiereFormulaSpecificationsDataProportioningService;


	/**
	 * 删除订单商品
	 *
	 * @param orderGoodsId
	 * @return
	 */
	@Transactional
	public Response<OrderDetailResponseVO> delete(Integer orderGoodsId) {
		Integer orderId =  deleteOrderGoods(orderGoodsId);
		return webOrderService.detail(orderId);
	}

	/**
	 * 删除订单商品
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public Object deleteByOrderId(Integer orderId) {
		List<LitemallOrderGoods> orderGoods = orderGoodsService.queryByOid(orderId);
		orderGoods.stream().forEach( orderGood -> {
			deleteOrderGoods(orderGood.getId());
		});
		orderService.deleteById(orderId);
		return ResponseUtil.ok();
	}


	public ResponseUtil.Response inserRemark(String remark,Integer orderGoodsId){
		if(StrUtil.isBlank(remark)){
			return ResponseUtil.ok();
		}
		boolean result = orderGoodsService.inserRemark(remark,orderGoodsId);
		return ResponseUtil.ok("备注添加成功");
	}



	public Object deleteNoLogical(Integer orderGoodsId) {
		if (orderGoodsId != null) {
			LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
			if (null == orderGoods) {
				return null;
			} else {
				//计算订单商品的价格
				BigDecimal goodsPrice = orderGoods.getSellingPrice().multiply(new BigDecimal(orderGoods.getNumber()));

				//修改订单金额
				Integer orderId = orderGoods.getOrderId();
				LitemallOrder order = orderService.findById(orderId);
				order.setOrderPrice(order.getOrderPrice().subtract(orderGoods.getPrice()));
				order.setTaxPrice(order.getTaxPrice().subtract(orderGoods.getTaxPrice()));
				order.setGoodsPrice(order.getGoodsPrice().subtract(goodsPrice));
				order.setActualPrice(order.getActualPrice().subtract(orderGoods.getPrice()));
				orderService.updateById(order);

				//删除订单商品
				orderGoodsService.deleteById(orderGoodsId);
				//删除订单商品属性
				litemallOrderGoodsPropertyService.deleteByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
				//删除订单商品辅料
				litemallOrderGoodsAccessoryService.deleteByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
				//删除订单商品税费
				litemallOrderTaxService.deleteByOrderIdAndOrderGoodsId(orderId, orderGoodsId);

				return webOrderService.detail(orderId);
			}

		}else{
			return ResponseUtil.fail(333,"订单商品编号不存在");
		}
	}

	/**
	 * 添加
	 * 添加订单商品
	 * <p>
	 * 如果订单中已经存在该商品，则增加数量，否则创建一个对象
	 *
	 * @param shopId  商店id
	 * @param request 请求体
	 * @return {@link Response}<{@link OrderDetailResponseVO}>
	 */
	@Transactional
	public Response<OrderDetailResponseVO> add(Integer shopId, OrderGoodsAddRequestVO request) {
		if(shopId == null) {
			return ResponseUtil.unlogin();
		}
		Integer goodsId = request.getGoodsId();
		LitemallGoods goods = goodsService.findById(goodsId);
		if(null == goods) {
			return ResponseUtil.fail(GOODS_UNKNOWN, "添加商品不存在");
		}else if(!goods.getIsOnSale()){
			return ResponseUtil.fail(GOODS_NOT_SALE,"商品已下架");
		}

		//获取订单
		Integer orderId = request.getOrderId();
		LitemallOrder order = orderService.findById(orderId);
		if (null == order) {
			return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
		}else if(Constants.ORDER_STATUS_NEW != order.getOrderStatus()) {
			return ResponseUtil.fail(ORDER_INVALID, "只有新建状态的订单才能添加商品");
		}

		//验证商品原料是否充足
		if(!isMerchandiseEnough(shopId, request)) {
			//原料不足
			return ResponseUtil.fail(ORDER_GOODS_MERCHANDISE_NOTENOUGH, "添加的商品原料不足");
		}


		Integer orderGoodsId = null;

		orderGoodsId = 	add(request, shopId, goods, order);

		return webOrderService.detailAndOrderGoodsId(orderId,orderGoodsId);
	}

	private Integer add(OrderGoodsAddRequestVO request, Integer shopId, LitemallGoods goods, LitemallOrder order) {
		Integer orderId = request.getOrderId();
		Integer goodsId = request.getGoodsId();
		//创建一个订单商品
		LitemallOrderGoods orderGoods = new LitemallOrderGoods();
		orderGoods.setOrderId(orderId);
		orderGoods.setShopId(shopId);
		orderGoods.setGoodsId(goods.getId());
		orderGoods.setGoodsName(goods.getName());
		orderGoods.setGoodsSn(goods.getGoodsSn());
		orderGoods.setCategoryId(goods.getCategoryId());
		orderGoods.setNumber(request.getNumber().shortValue());

		//查询规格信息和单价
		Integer specificationId = request.getSpecificationId();
		LitemallGoodsSpecification specification = goodsSpecificationService.findById(specificationId);
		BigDecimal unitPrice = specification.getPrice();
		orderGoods.setUnitPrice(unitPrice);
		String[] specifications = {specification.getSpecification()};
		orderGoods.setSpecifications(specifications);
		Integer[] specificationIds = {specificationId};
		orderGoods.setSpecificationIds(specificationIds);

		//保存订单商品
		orderGoodsService.add(orderGoods);
		Integer orderGoodsId = orderGoods.getId();

		//创建商品的售价临时变量
		BigDecimal sellingPrice = unitPrice;
		List<OrderGoodsAddAccessoryVO> accessoryList = request.getAccessoryList();
		if(!CollectionUtils.isEmpty(accessoryList)) {
			//创建辅料价格临时变量
			BigDecimal accessoryPrice = BigDecimal.ZERO;
			for (OrderGoodsAddAccessoryVO orderGoodsAddAccessoryVo : accessoryList) {

				Integer accessoryId = orderGoodsAddAccessoryVo.getAccessoryId();
				LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(accessoryId);

				LitemallOrderGoodsAccessory orderGoodsAccessory = new LitemallOrderGoodsAccessory();
				orderGoodsAccessory.setOrderId(orderId);
				orderGoodsAccessory.setOrderGoodsId(orderGoodsId);
				orderGoodsAccessory.setGoodsId(goodsId);
				orderGoodsAccessory.setAccessoryId(accessoryId);
				orderGoodsAccessory.setAccessoryName(accessory.getGroupName());
				orderGoodsAccessory.setReplaceId(0);
				orderGoodsAccessory.setMaster(5);
				orderGoodsAccessory.setDeleted(false);
				Integer number = orderGoodsAddAccessoryVo.getNumber();
				orderGoodsAccessory.setNumber(number);
				LitemallGoodsAccessory litemallGoodsAccessory = litemallGoodsAccessoryService.findById(accessoryId);
				List<LitemallGoodsSpecificationMerchandise> litemallGoodsSpecificationMerchandises = litemallGoodsSpecificationMerchandiseService.queryByGid(goodsId);


				Integer costType = accessory.getCostType();
				if(Constants.ACCESSORY_COST_TYPE_TIME == costType) {//按次计费只需增加一次费用
					orderGoodsAccessory.setPrice(accessory.getPrice());
				}else {//按份计算
					if(number>0) {
						orderGoodsAccessory.setPrice(accessory.getPrice().multiply(new BigDecimal(number)));
					}else {
						orderGoodsAccessory.setPrice(accessory.getPrice());
					}
				}

				litemallOrderGoodsAccessoryService.add(orderGoodsAccessory);

				accessoryPrice = accessoryPrice.add(orderGoodsAccessory.getPrice());
			}
			sellingPrice = sellingPrice.add(accessoryPrice);
		}
		orderGoods.setSellingPrice(sellingPrice);

		//计算商品的价格
		BigDecimal goodsPrice = sellingPrice.multiply(new BigDecimal(request.getNumber()));

		//获取店铺的地区id
		Integer regionId = getShopRegionId(shopId);
		LitemallGoodsRegion goodRegion = goodsRegionService.findByGidAndCityId(goodsId, regionId);
		if(null == goodRegion) {
//    		throw new RuntimeException("该店铺无操作商品的权限");
			throw new BusinessRuntimeException(ORDER_GOODS_SHOP_INVALID_OPERATION, "该店铺无操作商品的权限");
		}
		Integer[] taxTypes = goodRegion.getTaxTypes();

		BigDecimal taxPrice = BigDecimal.ZERO;
		for (int i = 0; i < taxTypes.length; i++) {
			Integer taxType = taxTypes[i];
			LitemallTax litemallTax = litemallTaxService.findById(taxType);
			if(null == litemallTax) {
//				throw new RuntimeException("未查询到区域税收配置");
				throw new BusinessRuntimeException(TAX_REGION_NOT_SET, "该区域未配置税收类型");
			}else if(litemallTax.getDeleted() || (!litemallTax.getEnable())) {
				continue;
			}

			//创建订单税收对象
			LitemallOrderTax orderTax = new LitemallOrderTax();
			orderTax.setOrderId(orderId);
			orderTax.setOrderGoodsId(orderGoodsId);
			orderTax.setGoodsId(goodsId);
			orderTax.setCode(litemallTax.getCode());
			//获取税收值
			BigDecimal value = litemallTax.getValue();
			orderTax.setValue(value);
			BigDecimal price = goodsPrice.multiply(value).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
			orderTax.setPrice(price);

			litemallOrderTaxService.add(orderTax);

			taxPrice = taxPrice.add(price);
		}
		orderGoods.setTaxPrice(taxPrice);
		BigDecimal price = goodsPrice.add(taxPrice);
		orderGoods.setPrice(price);
		orderGoodsService.updateById(orderGoods);

		//保存商品属性
		List<OrderGoodsAddPropertyVO> propertyList = request.getPropertyList();
		if(!CollectionUtils.isEmpty(propertyList)) {
			for (OrderGoodsAddPropertyVO orderGoodsAddPropertyVo : propertyList) {
				LitemallOrderGoodsProperty litemallOrderGoodsProperty = new LitemallOrderGoodsProperty();
				BeanUtils.copyProperties(orderGoodsAddPropertyVo, litemallOrderGoodsProperty);
				//TODO 属性名加值
				//litemallOrderGoodsProperty.setValue(orderGoodsAddPropertyVo.getName()+"/"+orderGoodsAddPropertyVo.getValue());
				litemallOrderGoodsProperty.setOrderId(orderId);
				litemallOrderGoodsProperty.setOrderGoodsId(orderGoodsId);
				litemallOrderGoodsProperty.setGoodsId(goodsId);

				litemallOrderGoodsPropertyService.add(litemallOrderGoodsProperty);
			}
		}

		//更新订单金额
		order.setGoodsPrice(order.getGoodsPrice().add(goodsPrice));
		order.setTaxPrice(order.getTaxPrice().add(taxPrice));
		order.setOrderPrice(order.getOrderPrice().add(price));
		order.setActualPrice(order.getActualPrice().add(price));
		orderService.updateById(order);

		return orderGoodsId;
	}





	@Transactional(rollbackFor = {Exception.class})
	public Response<OrderDetailResponseVO> update(Integer shopId, OrderGoodsAddRequestVO request) {
		List<LitemallGoodsSpecificationMerchandise> litemallGoodsSpecificationMerchandises = litemallGoodsSpecificationMerchandiseService.queryByGid(request.getGoodsId());
		LitemallOrderGoods orderGoods = orderGoodsService.findById(request.getOrderGoodsId());

			//需要删除的辅料
			List<Integer> accessoryIds = null;
			if(request.getAccessoryList().size() >0){
				accessoryIds = request.getAccessoryList().stream().map(OrderGoodsAddAccessoryVO::getAccessoryId).collect(Collectors.toList());
			}
			List<LitemallOrderGoodsAccessory> aList = litemallOrderGoodsAccessoryService.queryNotSelected(accessoryIds,request.getOrderGoodsId());
			BeanUtils.copyProperties(request,orderGoods);
			LitemallGoodsSpecification goodsSpecification = goodsSpecificationService.findById(request.getSpecificationId());
			orderGoods.setSpecifications(new String[]{goodsSpecification.getSpecification()});
			Integer[] specIds = new Integer[1];
			specIds[0] = request.getSpecificationId();

			orderGoods.setSpecificationIds(specIds);
			orderGoods.setNumber(request.getNumber().shortValue());

			LitemallGoodsSpecification specification = litemallGoodsSpecificationService.findById(request.getSpecificationId());
			BigDecimal totalPrice = new BigDecimal(0.0);
			if(specification != null){
				orderGoods.setUnitPrice(specification.getPrice().multiply(new BigDecimal(request.getNumber())));
				totalPrice = totalPrice.add(specification.getPrice().multiply(new BigDecimal(request.getNumber())));
			}

			//循环辅料列表
			List<OrderGoodsAddAccessoryVO> accessoryList = request.getAccessoryList();
			BigDecimal totalAccessoryPrice = BigDecimal.ZERO;
			if(accessoryList != null && accessoryList.size() > 0 ){

				for (int i = 0; i < accessoryList.size(); i++) {
					LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(accessoryList.get(i).getAccessoryId());
					LitemallOrderGoodsAccessory goodsAccessory =  litemallOrderGoodsAccessoryService.findByOrderGoodsIdAndAccessoryId(request.getOrderGoodsId(),accessoryList.get(i).getAccessoryId());
					BigDecimal accessoryPrice = BigDecimal.ZERO;
					if(goodsAccessory != null){
						goodsAccessory.setNumber(accessoryList.get(i).getNumber());

						if(accessoryList.get(i).getNumber() == 0){
							goodsAccessory.setDeleted(false);
						}
						Integer costType = accessory.getCostType();

						if (Constants.ACCESSORY_COST_TYPE_TIME == costType) {//按次计费只需增加一次费用
							accessoryPrice = accessory.getPrice();
							goodsAccessory.setPrice(accessoryPrice);
							accessoryPrice = accessoryPrice.multiply(new BigDecimal(request.getNumber()));
							totalPrice = totalPrice.add(accessoryPrice);
						} else {//按份计算
							if (goodsAccessory.getNumber() > 0) {
								accessoryPrice = accessory.getPrice().multiply(new BigDecimal(goodsAccessory.getNumber()));
								goodsAccessory.setPrice(accessoryPrice);
								accessoryPrice = accessoryPrice.multiply(new BigDecimal(request.getNumber()));
								totalPrice = totalPrice.add(accessoryPrice);
							}
						}


						litemallOrderGoodsAccessoryService.update(goodsAccessory);
					}else{
						LitemallOrderGoodsAccessory orderGoodsAccessory = new LitemallOrderGoodsAccessory();
						orderGoodsAccessory.setOrderId(request.getOrderId());
						orderGoodsAccessory.setOrderGoodsId(request.getOrderGoodsId());
						orderGoodsAccessory.setGoodsId(request.getGoodsId());
						orderGoodsAccessory.setAccessoryId(accessoryList.get(i).getAccessoryId());
						orderGoodsAccessory.setAccessoryName(accessory.getName());

						Integer number = accessoryList.get(i).getNumber();
						orderGoodsAccessory.setNumber(number);

						Integer costType = accessory.getCostType();
						if (Constants.ACCESSORY_COST_TYPE_TIME == costType) {//按次计费只需增加一次费用
							accessoryPrice = accessory.getPrice();
							orderGoodsAccessory.setPrice(accessoryPrice);
							accessoryPrice = accessoryPrice.multiply(new BigDecimal(request.getNumber()));
							totalPrice = totalPrice.add(accessoryPrice);
						} else {//按份计算
							if (number > 0) {
								accessoryPrice = accessory.getPrice().multiply(new BigDecimal(number));
								orderGoodsAccessory.setPrice(accessoryPrice);
								accessoryPrice = accessoryPrice.multiply(new BigDecimal(request.getNumber()));
								totalPrice = totalPrice.add(accessoryPrice);
							}
						}


						litemallOrderGoodsAccessoryService.add(orderGoodsAccessory);
					}
					totalAccessoryPrice = totalAccessoryPrice.add(accessoryPrice);

				}
			}
			orderGoods.setSellingPrice(orderGoods.getUnitPrice().add(totalAccessoryPrice));
			orderGoods.setDiscountPrice(orderGoods.getUnitPrice().add(totalAccessoryPrice));

			for (LitemallOrderGoodsAccessory orderGoodsAccessory : aList) {
				orderGoodsAccessory.setDeleted(true);
				litemallOrderGoodsAccessoryService.update(orderGoodsAccessory);
			}


//        //循环属性列表
			List<OrderGoodsAddPropertyVO> propertyList = request.getPropertyList();
			if(propertyList != null && propertyList.size() > 0){
				for (int i = 0; i < propertyList.size(); i++) {
					LitemallOrderGoodsProperty goodsProperty =  litemallOrderGoodsPropertyService.findByOrderGoodsIdAndGoodsPropertyId(request.getOrderGoodsId(),propertyList.get(i).getGoodsPropertyId());
					//TODO 属性名加值
					goodsProperty.setValue(propertyList.get(i).getValue());
					litemallOrderGoodsPropertyService.update(goodsProperty);
				}
			}

			//更新税费
			Integer regionId = getShopRegionId(shopId);
			LitemallGoodsRegion goodRegion = goodsRegionService.findByGidAndCityId(orderGoods.getGoodsId(), regionId);
			if(null == goodRegion) {
//    		throw new RuntimeException("该店铺无操作商品的权限");
				throw new BusinessRuntimeException(ORDER_GOODS_SHOP_INVALID_OPERATION, "该店铺无操作商品的权限");
			}
			Integer[] taxTypes = goodRegion.getTaxTypes();
			BigDecimal taxPrice = BigDecimal.ZERO;
			for (int i = 0; i < taxTypes.length; i++) {
				Integer taxType = taxTypes[i];
				LitemallTax litemallTax = litemallTaxService.findById(taxType);
				if(null == litemallTax) {
//				throw new RuntimeException("未查询到区域税收配置");
					throw new BusinessRuntimeException(TAX_REGION_NOT_SET, "该区域未配置税收类型");
				}else if(litemallTax.getDeleted() || (!litemallTax.getEnable())) {
					continue;
				}

				//创建订单税收对象
				List<LitemallOrderTax> orderTaxes = litemallOrderTaxService.queryByOrderIdAndOrderGoodsId(orderGoods.getOrderId(),orderGoods.getId());
				LitemallOrderTax orderTax = null;
				BigDecimal price = BigDecimal.ZERO;
				//对于订单商品而言税费的变化
				BigDecimal diffTaxPrice = BigDecimal.ZERO;

				if(orderTaxes == null || orderTaxes.size() == 0){
					orderTax = new LitemallOrderTax();
					orderTax.setOrderId(orderGoods.getOrderId());
					orderTax.setOrderGoodsId(orderGoods.getId());
					orderTax.setGoodsId(orderGoods.getGoodsId());
					orderTax.setCode(litemallTax.getCode());
					//获取税收值
					BigDecimal value = litemallTax.getValue();
					orderTax.setValue(value);
					price = orderGoods.getSellingPrice().multiply(value).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
					orderTax.setPrice(price);
					diffTaxPrice = price;
					litemallOrderTaxService.add(orderTax);
				}else{
					BigDecimal value = litemallTax.getValue();
					orderTax = litemallOrderTaxService.queryByOrderIdAndOrderGoodsIdAndCode(orderGoods.getOrderId(),orderGoods.getId(),litemallTax.getCode());
					if(orderTax != null){
						price	= orderGoods.getSellingPrice().multiply(value).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
						diffTaxPrice = price.subtract(orderTax.getPrice());
						orderTax.setPrice(price);
						litemallOrderTaxService.update(orderTax);
					}
				}
				taxPrice = orderGoods.getTaxPrice().add(diffTaxPrice);
				orderGoods.setTaxPrice(taxPrice);
			}

			orderGoods.setPrice(orderGoods.getSellingPrice().add(taxPrice));

			orderGoodsService.updateById(orderGoods);

			//TODO 更改订单商品之后更改订单价格
			//商品总费用 == 所有商品的售价
			// 商品税价  == 所有商品的税价
			// 实付费用  == 整个订单应付的价格
			// 订单费用  == 商品总费用加上税费
			BigDecimal goodsPrice = new BigDecimal(0.0);
			BigDecimal orderPrice = new BigDecimal(0.0);
			BigDecimal actualPrice = orderPrice;
			taxPrice =  new BigDecimal(0.0);
			LitemallOrder order = new LitemallOrder();
			List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderGoods.getOrderId());
			for (int i = 0; i < orderGoodsList.size(); i++) {
				goodsPrice = goodsPrice.add(orderGoodsList.get(i).getSellingPrice().multiply(new BigDecimal(orderGoodsList.get(i).getNumber())));
				taxPrice = taxPrice.add(orderGoodsList.get(i).getTaxPrice());
			}
			orderPrice = goodsPrice.add(taxPrice);
			//TODO 目前还没有打折，所以订单价格等于实际价格
			actualPrice = orderPrice;
			order.setId(orderGoods.getOrderId());
			order.setTaxPrice(taxPrice);
			order.setGoodsPrice(goodsPrice);
			order.setOrderPrice(orderPrice);
			order.setActualPrice(actualPrice);
			orderService.updateById2(order);


		return webOrderService.detailAndOrderGoodsId(orderGoods.getOrderId(),request.getOrderGoodsId());
	}



	/**
	 * 获取集合的长度
	 * @param list
	 * @return
	 */
	private Integer getListSize(List<?> list) {
		return list != null ?list.size():0;
	}

	/**
	 * 验证添加的商品原料是否足够
	 * @param shopId
	 * @param request
	 * @return
	 */
	private Boolean isMerchandiseEnough(Integer shopId, OrderGoodsAddRequestVO request) {
		List<Integer> merchandiseIdLs = new ArrayList<>();

		//查询规格原料
		Integer specId = request.getSpecificationId();
		List<LitemallGoodsSpecificationMerchandise> goodsSpecMerchandises = goodsSpecificationMerchandiseService.queryBySpecid(specId);
		for (LitemallGoodsSpecificationMerchandise goodsSpecMerchandise : goodsSpecMerchandises) {
			Integer merchandiseId = goodsSpecMerchandise.getMerchandiseId();
			if(!merchandiseIdLs.contains(merchandiseId)) {
				merchandiseIdLs.add(merchandiseId);
			}
		}

		//查询辅料原料
		List<OrderGoodsAddAccessoryVO> accessoryList = request.getAccessoryList();
		if(!CollectionUtils.isEmpty(accessoryList)) {
			for (OrderGoodsAddAccessoryVO accessoryVo : accessoryList) {
				LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(accessoryVo.getAccessoryId());
				Integer merchandiseId = accessory.getMerchandiseId();
				if(!merchandiseIdLs.contains(merchandiseId)) {
					merchandiseIdLs.add(merchandiseId);
				}
			}
		}

		for (Integer merchandiseId : merchandiseIdLs) {
			LitemallShopMerchandise litemallShopMerchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(merchandiseId, shopId);
			if(null == litemallShopMerchandise) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 更新数量
	 * 更新订单商品数量
	 *
	 * @param shopId  商店id
	 * @param request 请求
	 * @return {@link Response}<{@link OrderDetailResponseVO}>
	 */
	@Transactional
	public Response<OrderDetailResponseVO> updateNumber(Integer shopId, OrderGoodsUpdateNumberRequestVO request) {
		if(shopId == null) {
			return ResponseUtil.unlogin();
		}

		//查询订单商品
		Integer orderGoodsId = request.getOrderGoodsId();
		LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
		if(null == orderGoods) {
			return ResponseUtil.fail(ORDER_GOODS_UNKNOWN, "订单商品不存在");
		}

		Integer orderId = request.getOrderId();
		updateNumber(orderGoods, orderId, request.getNumber());
		return webOrderService.detail(orderId);
	}

	/**
	 * 更新商品数量
	 * @param orderGoods
	 * @param orderId
	 * @param num
	 */
	private void updateNumber(LitemallOrderGoods orderGoods, Integer orderId, Integer num) {
		Integer orderGoodsId = orderGoods.getId();
		//计算当前商品的总价
		BigDecimal number = new BigDecimal(num);
		BigDecimal goodsPrice = orderGoods.getSellingPrice().multiply(number);

		//计算税收金额
		BigDecimal taxPrice = BigDecimal.ZERO;
		List<LitemallOrderTax> orderTaxs = litemallOrderTaxService.queryByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
		if(!CollectionUtils.isEmpty(orderTaxs)) {
			for (LitemallOrderTax litemallOrderTax : orderTaxs) {
				BigDecimal price = goodsPrice.multiply(litemallOrderTax.getValue()).divide(new BigDecimal(100));
				litemallOrderTax.setPrice(price);

				litemallOrderTaxService.update(litemallOrderTax);
				taxPrice = taxPrice.add(price);
			}
		}

		//计算订单商品的总金额
		BigDecimal totalPrice = goodsPrice.add(taxPrice);
		//计算变动金额
		BigDecimal changeTaxPrice = taxPrice.subtract(orderGoods.getTaxPrice());
		BigDecimal changeGoodsPrice = orderGoods.getSellingPrice().multiply(number.subtract(new BigDecimal(orderGoods.getNumber())));
		BigDecimal changeTotalPrice = totalPrice.subtract(orderGoods.getPrice());

		//更新订单商品信息
		orderGoods.setNumber(number.shortValue());
		orderGoods.setTaxPrice(taxPrice);
		orderGoods.setPrice(totalPrice);
		orderGoodsService.updateById(orderGoods);

		//获取当前订单
		LitemallOrder order = orderService.findById(orderId);
		//更新订单金额
		order.setGoodsPrice(order.getGoodsPrice().add(changeGoodsPrice));
		order.setTaxPrice(order.getTaxPrice().add(changeTaxPrice));
		order.setOrderPrice(order.getOrderPrice().add(changeTotalPrice));
		order.setActualPrice(order.getActualPrice().add(changeTotalPrice));
		orderService.updateById(order);
	}

	/**
	 * 获取店铺的地区id
	 * @param shopId
	 */
	private Integer getShopRegionId(Integer shopId) {
		List<LitemallShopRegion> litemallShopRegions = shopRegionService.queryByShopId(shopId);
		if(!CollectionUtils.isEmpty(litemallShopRegions)) {
			for (LitemallShopRegion litemallShopRegion : litemallShopRegions) {
				LitemallRegion litemallRegion = regionService.findById(litemallShopRegion.getRegionId());
				if(Constants.REGION_TYPE_CITY == litemallRegion.getType()) {
					return litemallShopRegion.getRegionId();
				}
			}
		}
		return null;
	}

//	/**
//	 * 修改制作状态
//	 * @param orderGoodsId
//	 * @param madeStatus
//	 */
//	@Transactional
//	public Response<Object> updateMadeStatus(Integer orderGoodsId, Byte madeStatus,Integer userId,Integer index) {
//		String orderSn="";
//		Lock lock = new ReentrantLock();
//		try {
//			lock.lock();
//			LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
//			if (null == orderGoods) {
//				return ResponseUtil.fail(ORDER_GOODS_UNKNOWN, "订单商品不存在");
//			}
//
//			Integer orderId = orderGoods.getOrderId();
//			LitemallOrder litemallOrder = orderService.findById(orderId);
//			orderSn=litemallOrder.getOrderSn();
//			if (!Constants.ORDER_STATUS_ONGOING.equals(litemallOrder.getOrderStatus()) ) {
//				//进行中制作中的订单才能进行操作
//				return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
//			}
//			orderGoods.setMadeUserId(userId);
//
//			if(Constants.ORDER_GOODS_MADE_STATUS_NEW.equals(madeStatus)){
//				orderGoods.setMadeUserId(null);
//			}
//
//
//			orderGoods.getRemark().get(index).setIndexMakeStatus(madeStatus.intValue());
//			//如果是制作中
//			if(Constants.ORDER_GOODS_MADE_STATUS_ONGOING==madeStatus){
//				//修改订单商品的制作状态
//				orderGoods.setMadeStatus(madeStatus);
//			}
//			//如果是已完成
//			if(Constants.ORDER_GOODS_MADE_STATUS_FINISHED==madeStatus){
//				//修改订单商品的制作状态
//				//查看下标制作状态是否全部制作才算制作完成
//
//				long count = orderGoods.getRemark().stream().filter(indexMake -> indexMake.getIndexMakeStatus() != 2).count();
//				orderGoods.setMadeStatus(count==0?madeStatus:Constants.ORDER_GOODS_MADE_STATUS_ONGOING);
//			}
//			//如果是取消制作
//			if(Constants.ORDER_GOODS_MADE_STATUS_NEW==madeStatus){
//				//修改订单商品的制作状态
//				//查看下标制作状态是否全部制作才算制作完成
//				long count = orderGoods.getRemark().stream().filter(indexMake -> indexMake.getIndexMakeStatus() == 0).count();
//				orderGoods.setMadeStatus(count==orderGoods.getNumber()?madeStatus:Constants.ORDER_GOODS_MADE_STATUS_ONGOING);
//			}
//
//			orderGoodsService.updateById(orderGoods);
//
//			//如果为制作完成，则需要判断是否该订单的所有商品都已制作完成
//			if (Constants.ORDER_GOODS_MADE_STATUS_FINISHED.equals(madeStatus)) {
//				//订单量
//				int total = orderGoodsService.countByOrderIdAndMadeStatus(orderId, null);
//				//制作完成量
//				int finish = orderGoodsService.countByOrderIdAndMadeStatus(orderId, Constants.ORDER_GOODS_MADE_STATUS_FINISHED);
//				if (total == finish) {
//					LitemallOrder order = new LitemallOrder();
//					order.setId(orderId);
//					order.setMadeStatus(Constants.ORDER_MADE_STATUS_PICKUP);
//					orderService.updateById2(order);
//					noticeHelper.noticeShop(MESSAGE_TYPE_CHICKEN, JSON.toJSONString(order),orderGoods.getShopId());
//				}
//			}
//
//			//如果订单中有一个商品在制作，则将订单改成制作中
//			//拿到订单中所有的商品订单
//			List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
//			litemallOrder.setMadeStatus((byte)0);
//			orderService.updateById2(litemallOrder);
//			for(LitemallOrderGoods orderGoods1:orderGoodsList){
//				if(orderGoods1.getMadeStatus().intValue()==1||orderGoods1.getMadeStatus().intValue()==2){
//					litemallOrder.setMadeStatus((byte)1);
//					orderService.updateById2(litemallOrder);
//				}
//			}
//			//如果所有 完成商品订单数等于所有商品数，则将订单状态改成已完成
//			if(orderGoodsList.size()==orderGoodsList.stream().filter( maStatus -> maStatus.getMadeStatus()==2).collect(Collectors.toList()).size()){
//				litemallOrder.setMadeStatus((byte)2);
//				orderService.updateById2(litemallOrder);
//			}
//			lock.unlock();
//		}catch (Exception e){
//			lock.unlock();
//			log.debug("订单:{}制作异常了=====》开始回滚订单",orderSn);
//			//手动强制回滚事务，这里一定要第一时间处理
//			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//		}
//		return ResponseUtil.ok();
//	}

	/**
	 * 修改订单商品的制作状态。
	 *
	 * @param orderGoodsId 订单商品ID
	 * @param madeStatus   制作状态
	 * @param userId       用户ID
	 * @param index        备注索引
	 * @return 响应对象
	 */
	@Transactional
	public Response<Object> updateMadeStatus(Integer orderGoodsId, Byte madeStatus, Integer userId, Integer index) {
		String orderSn = "";
		Lock lock = new ReentrantLock();
		try {
			lock.lock();
			// 查询订单商品
			LitemallOrderGoods orderGoods = getOrderGoods(orderGoodsId);
			log.info("查询订单商品,订单商品的状态");
			if (orderGoods == null) {
				return ResponseUtil.fail(ORDER_GOODS_UNKNOWN, "订单商品不存在");
			}
			Integer orderId = orderGoods.getOrderId();
			log.info("订单商品的id:{}",orderId);
			// 查询订单信息
			LitemallOrder litemallOrder = getOrder(orderId);
			log.info("查询订单信息，订单的状态");
			orderSn = litemallOrder.getOrderSn();
			log.info("订单的编号:{}",orderSn);
			// 检查订单状态是否为进行中
			if (!isOrderOngoing(litemallOrder)) {
				return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
			}
			// 更新订单商品的制作状态
			updateOrderGoodsMadeStatus(orderGoods, madeStatus, userId, index);
			log.info("更新订单商品的制作状态");
			// 更新订单状态
			updateOrderStatus(orderGoods, litemallOrder);
			log.info("更新订单状态");
			// 解锁
			lock.unlock();
		} catch (Exception e) {
			// 异常处理，记录日志并回滚事务
			lock.unlock();
			log.debug("订单:{}制作异常，开始回滚订单", orderSn);
			rollbackTransaction();
			throw e; // 抛出异常
		}
		return ResponseUtil.ok();
	}

	/**
	 * 查询订单商品。
	 *
	 * @param orderGoodsId 订单商品ID
	 * @return 订单商品对象
	 */
	private LitemallOrderGoods getOrderGoods(Integer orderGoodsId) {
		return orderGoodsService.findById(orderGoodsId);
	}

	/**
	 * 查询订单信息。
	 *
	 * @param orderId 订单ID
	 * @return 订单对象
	 */
	private LitemallOrder getOrder(Integer orderId) {
		return orderService.findById(orderId);
	}

	/**
	 * 检查订单是否为进行中状态。
	 *
	 * @param litemallOrder 订单对象
	 * @return true表示进行中，false表示非进行中
	 */
	private boolean isOrderOngoing(LitemallOrder litemallOrder) {
		return Constants.ORDER_STATUS_ONGOING.equals(litemallOrder.getOrderStatus());
	}

	/**
	 * 更新订单商品的制作状态。
	 *
	 * @param orderGoods 订单商品对象
	 * @param madeStatus 制作状态
	 * @param userId     用户ID
	 * @param index      备注索引
	 */
	private void updateOrderGoodsMadeStatus(LitemallOrderGoods orderGoods, Byte madeStatus, Integer userId, Integer index) {
		if (madeStatus.equals(Constants.ORDER_GOODS_MADE_STATUS_NEW)) {
			orderGoods.setMadeUserId(null);
		} else {
			orderGoods.setMadeUserId(userId);
		}
		// 更新订单商品备注的制作状态
		updateOrderGoodsRemarkStatus(orderGoods, madeStatus, index);
		// 更新订单商品的制作状态
		orderGoods.setMadeStatus(madeStatus);
		orderGoodsService.updateById(orderGoods);
	}

	/**
	 * 更新订单商品备注的制作状态。
	 *
	 * @param orderGoods 订单商品对象
	 * @param madeStatus 制作状态
	 * @param index      备注索引
	 */
	private void updateOrderGoodsRemarkStatus(LitemallOrderGoods orderGoods, Byte madeStatus, Integer index) {
		List<WebOrderGoodsRemarkDTO> remarks = orderGoods.getRemark();
		if (remarks != null && index < remarks.size()) {
			remarks.get(index).setIndexMakeStatus(madeStatus.intValue());
		}
	}

	/**
	 * 更新订单状态。
	 *
	 * @param orderGoods   订单商品对象
	 * @param litemallOrder 订单对象
	 */
	private void updateOrderStatus(LitemallOrderGoods orderGoods, LitemallOrder litemallOrder) {
		if (Constants.ORDER_GOODS_MADE_STATUS_FINISHED.equals(orderGoods.getMadeStatus())) {
			updateOrderStatusForFinishedGoods(orderGoods, litemallOrder);
		} else if (Constants.ORDER_GOODS_MADE_STATUS_NEW.equals(orderGoods.getMadeStatus())) {
			updateOrderStatusForNewGoods(orderGoods, litemallOrder);
		}

		orderService.updateById2(litemallOrder);
	}

	/**
	 * 更新订单状态为制作完成。
	 *
	 * @param orderGoods   订单商品对象
	 * @param litemallOrder 订单对象
	 */
	private void updateOrderStatusForFinishedGoods(LitemallOrderGoods orderGoods, LitemallOrder litemallOrder) {
		// 查询订单中所有商品的总数
		int totalGoodsCount = orderGoodsService.countByOrderIdAndMadeStatus(litemallOrder.getId(),null);
		log.info("所有商品的总数:{}",totalGoodsCount);
		// 查询订单中已完成制作的商品数量
		int finishedGoodsCount = orderGoodsService.countByOrderIdAndMadeStatus(litemallOrder.getId(), Constants.ORDER_GOODS_MADE_STATUS_FINISHED);
		log.info("已完成制作的商品数量:{}",finishedGoodsCount);
		// 如果订单中的所有商品都已完成制作，则更新订单状态为待取货
		if (totalGoodsCount > 0 && totalGoodsCount == finishedGoodsCount) {
			litemallOrder.setMadeStatus(Constants.ORDER_MADE_STATUS_PICKUP);
			// 发送通知给商店
			noticeHelper.noticeShop(MESSAGE_TYPE_CHICKEN, JSON.toJSONString(litemallOrder), orderGoods.getShopId());
		}
	}


	/**
	 * 更新订单状态，当存在新商品时。
	 *
	 * @param orderGoods   订单商品对象
	 * @param litemallOrder 订单对象
	 */
	private void updateOrderStatusForNewGoods(LitemallOrderGoods orderGoods, LitemallOrder litemallOrder) {
		// 检查订单中是否有任何商品正在制作中，如果有，则更新订单状态为制作中；如果所有商品都制作完成，则更新订单状态为已完成
		List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(litemallOrder.getId());
		litemallOrder.setMadeStatus((byte) 0);
		for (LitemallOrderGoods goods : orderGoodsList) {
			if (goods.getMadeStatus().equals(Constants.ORDER_GOODS_MADE_STATUS_ONGOING) || goods.getMadeStatus().equals(Constants.ORDER_GOODS_MADE_STATUS_FINISHED)) {
				litemallOrder.setMadeStatus((byte) 1);
			}
		}
		if (orderGoodsList.size() == orderGoodsList.stream().filter(maStatus -> maStatus.getMadeStatus().equals(Constants.ORDER_GOODS_MADE_STATUS_FINISHED)).count()) {
			litemallOrder.setMadeStatus((byte) 2);
		}
	}

	/**
	 * 回滚事务。
	 */
	private void rollbackTransaction() {
		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
	}

	/**
	 * 配方
	 * 订单配方
	 *
	 * @param orderGoodsId 订单商品id
	 * @param userId       用户id
	 * @return {@link Response}<{@link OrderGoodsRecipeResponseVO}>
	 */
	@Transactional
	public Response<OrderGoodsRecipeResponseVO> recipe(Integer orderGoodsId, Integer userId) {
		LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
		if (null == orderGoods) {
			return ResponseUtil.fail(ORDER_GOODS_UNKNOWN, "订单商品不存在");
		}
		OrderGoodsRecipeResponseVO response = new OrderGoodsRecipeResponseVO();
		BeanUtils.copyProperties(orderGoods, response);

		if(orderGoods.getMadeUserId() != null){
			if(userId.equals(orderGoods.getMadeUserId())){
				response.setIsCooker(true);
			}else{
				response.setIsCooker(false);
			}
		}else{
			response.setIsCooker(true);
		}
		//查询规格辅料
		response.setSpecifications(orderGoods.getSpecifications()[0]);
		response.setPropertys(getGoodsPropertyStr(orderGoods.getId()));
		//response.setAccessory(getGoodsAccessoryStr(orderGoods.getId()));

		/*//查询规格辅料
		String[] specifications = orderGoods.getSpecifications();
		StringBuffer specAndAccessory = new StringBuffer(specifications[0]);
		//商品属性
		String property = getGoodsPropertyStr(orderGoods.getId());
		if (StringUtils.isNotBlank(property)) {
			specAndAccessory.append(" \r\n").append(property);
		}
		String accessory = getGoodsAccessoryStr(orderGoods.getId());
		if (StringUtils.isNotBlank(accessory)) {
			specAndAccessory.append(" \r\n").append(accessory);
		}
		response.setSpecAndAccessory(specAndAccessory.toString());*/

		List<OrderGoodsRecipeMerVO> merList = new ArrayList<>();
		Map<Integer, BigDecimal> merMap = caculateMerchandise(orderGoods, false);
		for (Integer merchandiseId : merMap.keySet()) {
			OrderGoodsRecipeMerVO recipeMerVo = new OrderGoodsRecipeMerVO();

			//查询原料信息
			LitemallMerchandise litemallMerchandise = litemallMerchandiseService.findById(merchandiseId);
			recipeMerVo.setMerchandiseId(merchandiseId);
			recipeMerVo.setMerchandiseName(litemallMerchandise.getName());
			recipeMerVo.setMerchandiseSn(litemallMerchandise.getMerchandiseSn());
			recipeMerVo.setNumber(merMap.get(merchandiseId));
			recipeMerVo.setUnit(litemallMerchandise.getBasicUnit());

			merList.add(recipeMerVo);
		}
		response.setMerList(merList);

		return ResponseUtil.ok(response);
	}

	/**
	 * 获取商品的属性字符串
	 * @param orderGoodsId
	 * @return
	 */
	private List getGoodsPropertyStr(Integer orderGoodsId) {
		List<LitemallOrderGoodsProperty> propertyList = litemallOrderGoodsPropertyService.queryByOrderGoodsId(orderGoodsId);
		if(!CollectionUtils.isEmpty(propertyList)) {
			List<Map> propertys = propertyList.stream().map(goodsProperty -> {
				Map map = CollUtil.newHashMap();
				map.put("name", goodsProperty.getName());
				map.put("value", goodsProperty.getValue());
				return map;
			}).collect(Collectors.toList());
			return propertys;
		}
		return CollUtil.newArrayList();
	}

	/**
	 * 获取商品的辅料字符串
	 * @param orderGoodsId
	 * @return
	 */
	private List getGoodsAccessoryStr(Integer orderGoodsId) {
		List<LitemallOrderGoodsAccessory> accessoryList = litemallOrderGoodsAccessoryService.findByOrderGoodsId(orderGoodsId);
		if(!CollectionUtils.isEmpty(accessoryList)) {
			List<Map> accessorys = accessoryList.stream().map(accessory -> {
				Map map = CollUtil.newHashMap();
				map.put("name", accessory.getAccessoryName());
				map.put("num", accessory.getNumber());
				return map;
			}).collect(Collectors.toList());
			return accessorys;
		}
		return CollUtil.newArrayList();
	}


	/**
	 * 计算订单商品的原料损耗
	 * @param litemallOrderGoods
	 * @param isConsumeRatio 是否计算原料损耗系数
	 * @return 原料损耗map <原料id，损耗的数量>
	 */
	private Map<Integer,BigDecimal> caculateMerchandise(LitemallOrderGoods litemallOrderGoods, boolean isConsumeRatio) {
		//创建原料损耗map <原料id，损耗的数量>
		Map<Integer,BigDecimal> merMap = new HashMap<>();

		//计算规格原料
		Integer specId = litemallOrderGoods.getSpecificationIds()[0];
		List<LitemallGoodsSpecificationMerchandise> goodsSpecMerchandises = goodsSpecificationMerchandiseService.queryBySpecid(specId);
		for (LitemallGoodsSpecificationMerchandise goodsSpecMerchandise : goodsSpecMerchandises) {
			Integer merchandiseId = goodsSpecMerchandise.getMerchandiseId();
			BigDecimal number = new BigDecimal(goodsSpecMerchandise.getNumber());
			if(isConsumeRatio) {//计算消耗系数
				number = number.multiply(goodsSpecMerchandise.getConsumeRatio());
			}

			BigDecimal merNumber = merMap.get(merchandiseId) ;
			if(null == merNumber) {
				merMap.put(merchandiseId, number);
			}else {
				merMap.put(merchandiseId, merNumber.add(merNumber));
			}
		}

		//计算辅料原料
		List<LitemallOrderGoodsAccessory> orderGoodsAccessorys = litemallOrderGoodsAccessoryService.findByOrderGoodsId(litemallOrderGoods.getId());
		for (LitemallOrderGoodsAccessory orderGoodsAccessory : orderGoodsAccessorys) {
			Integer accessoryId = orderGoodsAccessory.getAccessoryId();
			LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(accessoryId);

			Integer merchandiseId = accessory.getMerchandiseId();
			//计算辅料原料的损耗量 = 份数 * 每份辅料原料的数量  * 损耗系数
			BigDecimal number = new BigDecimal(orderGoodsAccessory.getNumber() * accessory.getNumber());
			if(isConsumeRatio) {//计算消耗系数
				number = number.multiply(accessory.getConsumeRatio());
			}

			BigDecimal merNumber = merMap.get(merchandiseId) ;
			if(null == merNumber) {
				merMap.put(merchandiseId, number);
			}else {
				merMap.put(merchandiseId, merNumber.add(merNumber));
			}
		}
		return merMap;
	}

	public Object orderGoodsList(Integer orderId) {
		List<LitemallOrderGoods> orderGoods = orderGoodsService.queryByOid(orderId);
		return ResponseUtil.okList(orderGoods);
	}

	public Response<LlitemallGoodsDetailVO> orderGoodsDetail(Integer orderGoodsId, Integer goodsId) {
		LitemallGoods goods = goodsService.findById(goodsId);
		if (null == goods) {
			return ResponseUtil.fail(GOODS_UNKNOWN, "商品不存在");
		}

		LlitemallGoodsDetailVO vo = new LlitemallGoodsDetailVO();
		BeanUtils.copyProperties(goods, vo);

		List<GoodsDetailSpecificationVO> specifications = new ArrayList<>();
		//商品中的规格
		List<LitemallGoodsSpecification> specList = specService.queryByGid(goodsId);

		//订单中选中的规格
		LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
		Integer[] specIds = orderGoods.getSpecificationIds();

		//规格中可能包含的merchandiseId
		List<Integer> merIds = new ArrayList<>();
		if (!CollectionUtils.isEmpty(specList)) {
			for (LitemallGoodsSpecification litemallGoodsSpecification : specList) {
				GoodsDetailSpecificationVO goodsDetailSpecVo = new GoodsDetailSpecificationVO();
				BeanUtils.copyProperties(litemallGoodsSpecification, goodsDetailSpecVo);

				//查询规格原料
				Integer specId = litemallGoodsSpecification.getId();
				List<LitemallGoodsSpecificationMerchandise> specMerList = specMerchandiseService.queryBySpecid(specId);
				List<GoodsDetailSpecMerVO> specMers = new ArrayList<>();
				for (LitemallGoodsSpecificationMerchandise litemallGoodsSpecificationMerchandise : specMerList) {
					merIds.add(litemallGoodsSpecificationMerchandise.getMerchandiseId());
					GoodsDetailSpecMerVO goodsDetailSpecMerVo = new GoodsDetailSpecMerVO();
					BeanUtils.copyProperties(litemallGoodsSpecificationMerchandise, goodsDetailSpecMerVo);
					specMers.add(goodsDetailSpecMerVo);
				}
				goodsDetailSpecVo.setSpecMers(specMers);

				boolean specFlag = false;

				for (int i = 0; i < specIds.length; i++) {
					if (specIds[i].equals(litemallGoodsSpecification.getId())) {
						specFlag = true;
						break;
					}
				}

				goodsDetailSpecVo.setIsSelected(specFlag);
				specifications.add(goodsDetailSpecVo);
			}
		}

		GoodsSpecificationsVO specificationsVo = new GoodsSpecificationsVO();
		specificationsVo.setName("大小");
		specificationsVo.setVos(specifications);
		vo.setSpecificationsVo(specificationsVo);

		//属性列表
		List<GoodsPropertyVO> propertyVos = new ArrayList<>();
		List<GoodsDetailPropVO> props = new ArrayList<>();

		//订单商品中的属性列表
		List<LitemallOrderGoodsProperty> orderGoodsProperties = litemallOrderGoodsPropertyService.queryByOrderGoodsId(orderGoodsId);

		List<String> orderGoodsValues = new ArrayList<>();
		for (int i = 0; i < orderGoodsProperties.size(); i++) {
			orderGoodsValues.add(orderGoodsProperties.get(i).getValue());
		}

		List<LitemallGoodsProperty> propList = goodsPropertyService.queryByGoodsId(goodsId);
		if (!CollectionUtils.isEmpty(propList)) {
			for (LitemallGoodsProperty litemallGoodsProperty : propList) {
				GoodsPropertyVO propertyVo = new GoodsPropertyVO();
				propertyVo.setId(litemallGoodsProperty.getId());
				propertyVo.setName(litemallGoodsProperty.getName());

				List<GoodsDetailPropertyVO> vos = new ArrayList<GoodsDetailPropertyVO>();
				String[] values = litemallGoodsProperty.getValues();
				for (int i = 0; i < values.length; i++) {
					GoodsDetailPropertyVO v = new GoodsDetailPropertyVO();
					v.setName(values[i]);

					boolean propertyFlag = false;
					for (int i1 = 0; i1 < orderGoodsValues.size(); i1++) {
						if (orderGoodsValues.get(i1).equals(values[i])) {
							propertyFlag = true;
							break;
						}
					}

					v.setIsSelected(propertyFlag);

					vos.add(v);
				}
				propertyVo.setVos(vos);
				propertyVos.add(propertyVo);
			}
		}
		vo.setPropertyVos(propertyVos);

		//
		List<LitemallGoodsAccessoryGroup> groups = goodsAccessoryGroupService.queryByGid(goods.getId());



		//咖啡因
		List<GoodsAccessoryVO> accessoryVos = new ArrayList<>();
		GoodsAccessoryVO accessoryVo1 = new GoodsAccessoryVO();
		accessoryVo1.setName("咖啡因");
		GoodsAccessoryVO accessoryVo2 = new GoodsAccessoryVO();
		accessoryVo2.setName("糖浆");
		GoodsAccessoryVO accessoryVo3 = new GoodsAccessoryVO();
		accessoryVo3.setName("牛奶");
		GoodsAccessoryVO accessoryVo4 = new GoodsAccessoryVO();
		accessoryVo4.setName("其他");
		GoodsAccessoryVO accessoryVo5 = new GoodsAccessoryVO();
		accessoryVo5.setName("配料");
		GoodsAccessoryVO accessoryVo6 = new GoodsAccessoryVO();
		accessoryVo6.setName("奶泡");
		GoodsAccessoryVO accessoryVo7 = new GoodsAccessoryVO();
		accessoryVo7.setName("浓缩计量");
		groups.stream().forEach( group -> {
//			caffeine
			if(group.getName().toLowerCase().equalsIgnoreCase("caffeine") || group.getName().contains("咖啡因")){
				List<LitemallGoodsDetailAccessoryVO> vos =  beanReverse(group.getId(),merIds,orderGoodsId,goodsId);
				accessoryVo1.setVos(vos);
			}else if(group.getName().toLowerCase().equalsIgnoreCase("syrups") || group.getName().contains("糖浆")){
				List<LitemallGoodsDetailAccessoryVO> vos =  beanReverse(group.getId(),merIds,orderGoodsId,goodsId);
				accessoryVo2.setVos(vos);
			}else if(group.getName().toLowerCase().equalsIgnoreCase("milk") || group.getName().contains("牛奶")){

				List<LitemallGoodsDetailAccessoryVO> vos =  beanReverse(group.getId(),merIds,orderGoodsId,goodsId);
				accessoryVo3.setVos(vos);
			} else if(group.getName().toLowerCase().equalsIgnoreCase("Toppings") || group.getName().contains("配料")){

				List<LitemallGoodsDetailAccessoryVO> vos =  beanReverse(group.getId(),merIds,orderGoodsId,goodsId);
				accessoryVo5.setVos(vos);
			}else if(group.getName().toLowerCase().equalsIgnoreCase("Cold Foam") || group.getName().contains("奶泡")){

				List<LitemallGoodsDetailAccessoryVO> vos =  beanReverse(group.getId(),merIds,orderGoodsId,goodsId);
				accessoryVo6.setVos(vos);
			}else if(group.getName().toLowerCase().equalsIgnoreCase("Add Shot") || group.getName().contains("浓缩计量")){

				List<LitemallGoodsDetailAccessoryVO> vos =  beanReverse(group.getId(),merIds,orderGoodsId,goodsId);
				accessoryVo7.setVos(vos);
			}
			else{
				List<LitemallGoodsDetailAccessoryVO> vos =  beanReverse(group.getId(),merIds,orderGoodsId,goodsId);
				accessoryVo4.setVos(vos);
			}
		});

		List<LitemallGoodsDetailAccessoryVO> vs = new ArrayList();

		if(accessoryVo1.getVos() == null){
			accessoryVo1.setVos(vs );
		}

		if(accessoryVo2.getVos() == null){
			accessoryVo2.setVos(vs );
		}

		if(accessoryVo3.getVos() == null){
			accessoryVo3.setVos(vs );
		}

		if(accessoryVo4.getVos() == null){
			accessoryVo4.setVos( vs  );
		}
		if(accessoryVo5.getVos() == null){
			accessoryVo5.setVos( vs  );
		}
		if(accessoryVo6.getVos() == null){
			accessoryVo6.setVos( vs  );
		}
		if(accessoryVo7.getVos() == null){
			accessoryVo7.setVos( vs  );
		}
		accessoryVos.add(accessoryVo1);
		accessoryVos.add(accessoryVo2);
		accessoryVos.add(accessoryVo3);
		accessoryVos.add(accessoryVo4);
		accessoryVos.add(accessoryVo5);
		accessoryVos.add(accessoryVo6);
		accessoryVos.add(accessoryVo7);
		vo.setAccessoryVos(accessoryVos);
		vo.setOrderGoodsId(orderGoodsId);
		vo.setNumber(orderGoods != null ? orderGoods.getNumber() : 1);
		return ResponseUtil.ok(vo);
	}

	public List<LitemallGoodsDetailAccessoryVO> beanReverse(Integer groupId, List<Integer> merIds, Integer orderGoodsId, Integer goodsId) {
		List<LitemallGoodsAccessory> accessories = accessoryService.queryByGroupId(groupId);
		List<LitemallGoodsDetailAccessoryVO> vos = accessories.stream().map(accessory -> {
			boolean flag = false;
			LitemallMerchandise merchandise = litemallMerchandiseService.findById(accessory.getMerchandiseId());
			LitemallGoodsDetailAccessoryVO vo = new LitemallGoodsDetailAccessoryVO();

			BeanUtils.copyProperties(accessory,vo);
			vo.setId(accessory.getId());
			vo.setName(accessory.getGroupName());
			vo.setCostType(accessory.getCostType());
			vo.setUnit(merchandise.getUnit());
			vo.setMerchandiseId(merchandise.getId());

			//查看在规格中是否有这个辅料
			for (int i = 0; i < merIds.size(); i++) {
				if(merchandise.getId().equals(merIds.get(i))){
					flag = true;
					break;
				}
			}
				LitemallOrderGoodsAccessory orderGoodsAccessory = litemallOrderGoodsAccessoryService.findByOrderGoodsIdAndAccessoryId(orderGoodsId,accessory.getId());
				if(orderGoodsAccessory != null){
				vo.setSelectedNum( orderGoodsAccessory.getNumber() == null  ? 0 : orderGoodsAccessory.getNumber());
				vo.setReplaceId(orderGoodsAccessory.getReplaceId());
				vo.setMaster(orderGoodsAccessory.getMaster());
				flag = true;

				if(orderGoodsAccessory.getNumber().equals(0) || orderGoodsAccessory.getNumber() == null){
					flag = false;
				}else{
					flag = true;
				}

			}else{
				vo.setSelectedNum(0);
				flag = false;
			}
			vo.setIsDefaultValue(flag);

			/*LitemallGoodsAccessory accessoryServiceOne = accessoryService.getOne(Wrappers.lambdaQuery(LitemallGoodsAccessory.class)
					.eq(LitemallGoodsAccessory::getMerchandiseId, merchandise.getId())
					.eq(LitemallGoodsAccessory::getGoodsId,goodsId));*/
			vo.setPrice(accessory.getPrice());
			vo.setIsSelected(flag);
			vo.setNumber(orderGoodsAccessory == null ? 0 : orderGoodsAccessory.getNumber());
			return vo;
		}).collect(Collectors.toList());
		return vos;
	}

	public Object orderDetail(Integer orderId) {
		return webOrderService.detail(orderId);
	}



	public Object outStandingInShop(Integer shopId,Integer userId,Integer page,Integer limit){
		List<LitemallOrder> litemallOrders = orderService.recipeDoingByMadeStatusInShop(Arrays.asList(new Byte[]{0,1}),shopId);
		List<OrderGoodsRecipeResponseVO> orderGoods = new ArrayList<>();
		for (LitemallOrder order : litemallOrders) {
			//订单商品
			orderGoods.addAll(getOrderGoods(order.getGoodsIds(), userId,order.getUserId(),order));
			//订单套餐
			List<OrderPackageGoodsRecipeRespVO> orderPackageGoods = getOrderPackageGoods(order.getPackageIds(), userId,order.getUserId(),order);
			orderPackageGoods.forEach(goods->orderGoods.addAll(goods.getOrderGoodsList()));
		}
		CollUtil.filter(orderGoods, (Filter<OrderGoodsRecipeResponseVO>) item->item.getMadeStatus() != ORDER_GOODS_MADE_STATUS_FINISHED);
		PageTools pageTools =PageTools.builder().build();
		pageTools.pageTools(page,limit,orderGoods);
		return ResponseUtil.ok(pageTools);
	}

	public List<OrderPackageGoodsRecipeRespVO> getOrderPackageGoods(List<Integer> packageIds, Integer userId,Integer orderUserId,LitemallOrder order){
		if(packageIds.size()==0)return new ArrayList<>();
		List<LitemallOrderPackage> orderPackages = litemallOrderPackageService.listByIds(packageIds);
		//套餐+[商品]
		List<OrderPackageGoodsRecipeRespVO> orderPackageGoodsRecipeResList = new ArrayList<>();
		for (LitemallOrderPackage orderPackage : orderPackages) {
			List<OrderGoodsRecipeResponseVO> orderGoods = getOrderGoods(orderPackage.getGoodsIds(), userId,orderUserId,order);
			orderPackageGoodsRecipeResList.add(new OrderPackageGoodsRecipeRespVO(orderPackage,orderGoods));
		}
		return orderPackageGoodsRecipeResList;
	}

	private List<OrderGoodsRecipeResponseVO> getOrderGoods(List<Integer> goodsIds,Integer userId,Integer orderUserId,LitemallOrder order){
		if(goodsIds.size()==0)return new ArrayList<>();
		List<LitemallOrderGoods> orderGoods = orderGoodsService.getOrderGoodsByIds(goodsIds);
		//所有商品集合
		List<OrderGoodsRecipeResponseVO> orderGoodsRecipeList = new ArrayList<>();

		for (LitemallOrderGoods orderGood : orderGoods) {
			//封装每一项
			OrderGoodsRecipeResponseVO orderGoodVO = BeanUtil.toBean(orderGood, OrderGoodsRecipeResponseVO.class);
			orderGoodVO.setIsCooker(orderGood.getMadeUserId() != null&&userId.equals(orderGood.getMadeUserId()));
			//查询规格辅料
			orderGoodVO.setSpecifications(orderGood.getSpecifications()[0]);
			orderGoodVO.setPropertys(getGoodsPropertyStr(orderGood.getId()));
			//配方
			List<LitemallOrderFormulaMaterial> orderFormulaMaterials = litemallOrderFormulaMaterialService
					.list(Wrappers.lambdaQuery(LitemallOrderFormulaMaterial.class)
					.eq(LitemallOrderFormulaMaterial::getOrderGoodsId,orderGood.getId()));
			orderGoodVO.setFormulaMaterials(orderFormulaMaterials);

			List<OrderGoodsRecipeMerVO> merList = new ArrayList<>();
			Map<Integer, BigDecimal> merMap = caculateMerchandise(orderGood, false);
			for (Integer merchandiseId : merMap.keySet()) {
				OrderGoodsRecipeMerVO recipeMerVo = new OrderGoodsRecipeMerVO();

				//查询原料信息
				LitemallMerchandise litemallMerchandise = litemallMerchandiseService.findById(merchandiseId);
				recipeMerVo.setMerchandiseId(merchandiseId);
				recipeMerVo.setMerchandiseName(litemallMerchandise.getName());
				recipeMerVo.setMerchandiseSn(litemallMerchandise.getMerchandiseSn());
				recipeMerVo.setNumber(merMap.get(merchandiseId));
				recipeMerVo.setUnit(litemallMerchandise.getBasicUnit());

				merList.add(recipeMerVo);
			}
			//orderGoodVO.setMessage(JSONUtil.toJsonStr(orderGood.getRemark()));
			orderGoodVO.setGoodsRemarks(orderGood.getRemark());
			orderGoodVO.setMerList(merList);
			orderGoodVO.setOrderTime(orderGood.getAddTime().toLocalTime().toString());
			//下单用户
			orderGoodVO.setNickname(userService.getById(orderUserId).getNickname());
			orderGoodVO.setOrderType(order.getOrderType());
			orderGoodsRecipeList.add(orderGoodVO);
		}
		return orderGoodsRecipeList;
	}


	public OrderGoodsRecipeResponseVO recipeInCook(LitemallOrderGoods orderGoods, Integer userId, Integer order, Integer size) {
		if (null == orderGoods) {
			return null;
		}

		OrderGoodsRecipeResponseVO response = new OrderGoodsRecipeResponseVO();
		BeanUtils.copyProperties(orderGoods, response);

		//response.setGoodsNum(size);
		/*if(orderGoods.getMadeUserId() != null){
			if(userId.equals(orderGoods.getMadeUserId())){
				response.setIsCooker(true);
			}else{
				response.setIsCooker(false);
			}
		}else{
			response.setIsCooker(true);
		}*/

		response.setIsCooker(orderGoods.getMadeUserId() != null&&userId.equals(orderGoods.getMadeUserId()));

		//查询规格辅料
		response.setSpecifications(orderGoods.getSpecifications()[0]);
		response.setPropertys(getGoodsPropertyStr(orderGoods.getId()));

		//response.setIsFormula(orderGoods.getIsFormula());

		//配方
		List<LitemallOrderFormulaMaterial> orderFormulaMaterials = litemallOrderFormulaMaterialService.list(Wrappers.lambdaQuery(LitemallOrderFormulaMaterial.class).eq(LitemallOrderFormulaMaterial::getOrderGoodsId,orderGoods.getId()));
		response.setFormulaMaterials(orderFormulaMaterials);

		//response.setAccessory(getGoodsAccessoryStr(orderGoods.getId()));

		/*StringBuffer specAndAccessory = new StringBuffer(specifications[0]);
		//商品属性
		String property = getGoodsPropertyStr(orderGoods.getId());
		if (StringUtils.isNotBlank(property)) {
			specAndAccessory.append("\r\n").append(property);
		}
		String accessory = getGoodsAccessoryStr(orderGoods.getId());
		if (StringUtils.isNotBlank(accessory)) {
			specAndAccessory.append("\r\n").append(accessory);
		}
		response.setSpecAndAccessory(specAndAccessory.toString());*/

        List<OrderGoodsRecipeMerVO> merList = new ArrayList<>();
        Map<Integer, BigDecimal> merMap = caculateMerchandise(orderGoods, false);
        for (Integer merchandiseId : merMap.keySet()) {
			OrderGoodsRecipeMerVO recipeMerVo = new OrderGoodsRecipeMerVO();

			//查询原料信息
			LitemallMerchandise litemallMerchandise = litemallMerchandiseService.findById(merchandiseId);
			recipeMerVo.setMerchandiseId(merchandiseId);
			recipeMerVo.setMerchandiseName(litemallMerchandise.getName());
			recipeMerVo.setMerchandiseSn(litemallMerchandise.getMerchandiseSn());
			recipeMerVo.setNumber(merMap.get(merchandiseId));
			recipeMerVo.setUnit(litemallMerchandise.getBasicUnit());

			merList.add(recipeMerVo);
		}



		//辅料
		/*List<OrderGoodsRecipeMerVO> merList = new ArrayList<>();
		List<LitemallOrderGoodsAccessory> goodsAccessories = litemallOrderGoodsAccessoryService.findByOrderGoodsId(orderGoods.getId());
		for (int i = 0; i < goodsAccessories.size(); i++) {
			OrderGoodsRecipeMerVO recipeMerVo = new OrderGoodsRecipeMerVO();
			recipeMerVo.setMerchandiseName(goodsAccessories.get(i).getAccessoryName());
			recipeMerVo.setNumber(new BigDecimal(goodsAccessories.get(i).getNumber()));
			merList.add(recipeMerVo);
		}*/
		//response.setMessage(JSONUtil.toJsonStr(orderGoods.getRemark()));
		response.setMerList(merList);
		//response.setOrder(order);
		response.setOrderTime(orderGoods.getAddTime().toLocalTime().toString());

		return response;
	}

	public Integer deleteOrderGoods(Integer orderGoodsId){
		LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
		if (null == orderGoods) {
			return null;
		}

		//计算订单商品的价格
		BigDecimal goodsPrice = orderGoods.getSellingPrice().multiply(new BigDecimal(orderGoods.getNumber()));

		//修改订单金额
		Integer orderId = orderGoods.getOrderId();
		LitemallOrder order = orderService.findById(orderId);
		order.setOrderPrice(order.getOrderPrice().subtract(orderGoods.getPrice()));
		order.setTaxPrice(order.getTaxPrice().subtract(orderGoods.getTaxPrice()));
		order.setGoodsPrice(order.getGoodsPrice().subtract(goodsPrice));
		order.setActualPrice(order.getActualPrice().subtract(orderGoods.getPrice()));
		orderService.updateById(order);

		//删除订单商品
		orderGoodsService.deleteById(orderGoodsId);
		//删除订单商品属性
		litemallOrderGoodsPropertyService.deleteByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
		//删除订单商品辅料
		litemallOrderGoodsAccessoryService.deleteByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
		//删除订单商品税费
		litemallOrderTaxService.deleteByOrderIdAndOrderGoodsId(orderId, orderGoodsId);

		return orderId;
	}

	public Object getOrderGoodsDetailVos(Integer orderGoodsId){
		LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);

		//订单
		LitemallOrder order = orderService.findById(orderGoods.getOrderId());

		//属性
		List<LitemallOrderGoodsProperty> orderGoodsProperties = litemallOrderGoodsPropertyService.queryByOrderGoodsId(orderGoodsId);

		//辅料
		List<LitemallOrderGoodsAccessory> orderGoodsAccessories = litemallOrderGoodsAccessoryService.findByOrderGoodsId(orderGoodsId);

		//会员名称
		LitemallOrderGoodsDetailVO vo = new LitemallOrderGoodsDetailVO();
		if(order.getMemberId() != null){
			LitemallUser user = userService.findById(order.getMemberId());
			vo.setUserName(user.getUsername());
		}

		//规格
		if(orderGoods.getSpecifications().length > 0){
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < orderGoods.getSpecifications().length; i++) {
				sb.append(orderGoods.getSpecifications()[i]);

				if(i != orderGoods.getSpecifications().length - 1){
					sb.append(" ,");
				}
			}

			vo.setSpecifications(sb.toString());
			sb = null;
		}

		//属性
		if(orderGoodsProperties.size() > 0){
			StringBuffer psb = new StringBuffer();
			for (int i = 0; i < orderGoodsProperties.size(); i++) {
				psb.append(orderGoodsProperties.get(i).getValue());

				if(i != orderGoodsProperties.size() -1 ){
					psb.append(" ,");
				}
			}
			vo.setProperties(psb.toString());
			psb = null;
		}

		//商品名称
		vo.setGoodsName(orderGoods.getGoodsName());

		//辅料
		List<LitemallOrderGoodsAccesoryVO> accesoryVos = orderGoodsAccessories.stream().map(accessory -> {
			LitemallOrderGoodsAccesoryVO accesoryVo = new LitemallOrderGoodsAccesoryVO();
			accesoryVo.setNumber(accessory.getNumber());
			accesoryVo.setName(accessory.getAccessoryName());
			accesoryVo.setPrice(accessory.getPrice());
			return accesoryVo;
		}).collect(Collectors.toList());

		vo.setAccesoryVos(accesoryVos);
		vo.setMessage(order.getMessage());
		vo.setPayTime(order.getPayTime().toLocalTime().toString());

		return  ResponseUtil.ok(vo);
	}

	public Response<OrderDetailResponseVO> getNewOrder(Integer shopId, Integer userId){
		List<LitemallOrder> orders =  orderService.getNewOrderByUserId(shopId,userId);
		if(orders != null && orders.size() > 0){
			LitemallOrder order = orders.get(0);
			return webOrderService.detailAndOrderGoodsId(order.getId(),null);
		}else{
			return ResponseUtil.ok();
		}
	}

	private OrderGoodsCheckRespVO checkShopMaterial(Integer shopId, WebOrderGoodsCheckOut orderGoodsCheckOut){
		List<String> materialNameList = CollUtil.newArrayList();
		//商品
		for (WebGoodsCheckOut checkOutGood : orderGoodsCheckOut.getGoods()) {
			OrderPackageGoodsFormulasVO goodsFormula = checkOutGood.getGoodsFormulas();
			//主料
			for (List<OrderFormulaSpecificationsMaterialVO> orderFormulaSpecificationsMaterialMaster : goodsFormula.getFormulaSpecificationsDataProportioningsMaster()) {
				for (OrderFormulaSpecificationsMaterialVO orderFormulaSpecificationsMaterialVO : orderFormulaSpecificationsMaterialMaster) {
					if(!orderFormulaSpecificationsMaterialVO.getIsDefault())continue;
					LumiereFormulaSpecificationsDataProportioning proportioningServiceById = lumiereFormulaSpecificationsDataProportioningService.getById(orderFormulaSpecificationsMaterialVO.getFormulaSpecificationsDataProportioningId());
					merchandiseSubtract(materialNameList,orderFormulaSpecificationsMaterialVO.getMaterialId(),orderFormulaSpecificationsMaterialVO.getQuantity()*checkOutGood.getNumber()*proportioningServiceById.getSpecificationsDose(), shopId);
				}
			}
			//辅料
			for (List<OrderFormulaSpecificationsMaterialVO> orderFormulaSpecificationsMaterialSlave : goodsFormula.getFormulaSpecificationsDataProportioningsSlave()) {
				for (OrderFormulaSpecificationsMaterialVO orderFormulaSpecificationsMaterialVO : orderFormulaSpecificationsMaterialSlave) {
					if(!orderFormulaSpecificationsMaterialVO.getIsDefault())continue;
					LumiereFormulaSpecificationsDataProportioning proportioningServiceById = lumiereFormulaSpecificationsDataProportioningService.getById(orderFormulaSpecificationsMaterialVO.getFormulaSpecificationsDataProportioningId());
					merchandiseSubtract(materialNameList,orderFormulaSpecificationsMaterialVO.getMaterialId(),orderFormulaSpecificationsMaterialVO.getQuantity()*checkOutGood.getNumber()*proportioningServiceById.getSpecificationsDose(), shopId);
				}
			}
		}

		//套餐
		for (OrderPackageCheckOutVO checkOutPackageGood : orderGoodsCheckOut.getPackageGoods()) {
			for (OrderPackageGoodsCheckOutVO checkOutGood : checkOutPackageGood.getGoods()) {
				OrderPackageGoodsFormulasVO goodsFormula = checkOutGood.getGoodsFormulas();
				//主料
				for (List<OrderFormulaSpecificationsMaterialVO> orderFormulaSpecificationsMaterialMaster : goodsFormula.getFormulaSpecificationsDataProportioningsMaster()) {
					for (OrderFormulaSpecificationsMaterialVO orderFormulaSpecificationsMaterialVO : orderFormulaSpecificationsMaterialMaster) {
						if(!orderFormulaSpecificationsMaterialVO.getIsDefault())continue;
						merchandiseSubtract(materialNameList,orderFormulaSpecificationsMaterialVO.getMaterialId(),orderFormulaSpecificationsMaterialVO.getQuantity()*checkOutPackageGood.getNumber().doubleValue(), shopId);
					}
				}
				//辅料
				for (List<OrderFormulaSpecificationsMaterialVO> orderFormulaSpecificationsMaterialSlave : goodsFormula.getFormulaSpecificationsDataProportioningsSlave()) {
					for (OrderFormulaSpecificationsMaterialVO orderFormulaSpecificationsMaterialVO : orderFormulaSpecificationsMaterialSlave) {
						if(!orderFormulaSpecificationsMaterialVO.getIsDefault())continue;
						merchandiseSubtract(materialNameList,orderFormulaSpecificationsMaterialVO.getMaterialId(),orderFormulaSpecificationsMaterialVO.getQuantity()*checkOutPackageGood.getNumber().doubleValue(), shopId);
					}
				}
			}
		}
		return new OrderGoodsCheckRespVO(materialNameList.size()>0,materialNameList);
	}

	private List<String> merchandiseSubtract(List<String> materialNameList,Integer materialId,Double quantity,Integer shopId){
		//对比每一个的库存
		LitemallMerchandise merchandise = litemallMerchandiseService.findById(materialId);
		if (merchandise==null){
			materialNameList.add("");
			return materialNameList;
		}
		LitemallShopMerchandise shopMerchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(merchandise.getId(), shopId);
		if (shopMerchandise==null){
			materialNameList.add(merchandise.getName());
			return materialNameList;
		}
		if(shopMerchandise.getBasicNumber()<quantity){
			//原料不足
			materialNameList.add(merchandise.getName());
		}else {
			//减去库存
			Double basicNumber = shopMerchandise.getBasicNumber()-quantity;
			Double number = basicNumber/merchandise.getCheckRatio();
			shopMerchandise.setNumber(NumberUtil.roundDown(number,2).doubleValue());
			shopMerchandise.setBasicNumber(NumberUtil.roundDown(basicNumber,2).doubleValue());
			shopMerchandise.setStockNumber(NumberUtil.roundDown(number/merchandise.getRatio(),2).doubleValue());
			litemallShopMerchandiseService.updateById(shopMerchandise);
		}
		return materialNameList;
	}


	/**
	 * 订单商品结算 (收银端付款功能)
	 * 去掉锁
	 * @param shopId
	 * @param userId
	 * @param orderGoodsCheckOut
	 * @return
	 */
	public Response goodsCheckOut(Integer shopId, Integer userId, WebOrderGoodsCheckOut orderGoodsCheckOut) {
		try {
			//检测原料库存
			OrderGoodsCheckRespVO orderGoodsCheckRespVO = checkShopMaterial(shopId, orderGoodsCheckOut);
			if(orderGoodsCheckRespVO.getCheckResult()){
				return ResponseUtil.fail(ErrorCodeConstants.LUMIERE_ORDER_GOODS_MERCHANDISE_NOTENOUGH.getCode(),orderGoodsCheckRespVO.getMaterialNameList().toString());
			}

			// 查询用户和余额
			LitemallUser litemallUser = getUserAndBalance(orderGoodsCheckOut.getMembershipNumber());
			log.info("查询用户和余额,用户是");
			// 创建订单
			LitemallOrder litemallOrder = createOrder(shopId, userId, orderGoodsCheckOut, litemallUser);
			log.info("创建订单,订单的状态是");
			// 创建订单商品
			createOrderGoods(orderGoodsCheckOut.getGoods(), litemallOrder);

			//创建订单套餐
			createOrderPackageGoods(orderGoodsCheckOut, litemallOrder);

			log.info("创建订单商品");
			// 如果使用了优惠券，更新优惠券信息
			updateCoupon(orderGoodsCheckOut, litemallOrder);
			log.info("如果使用了优惠券，更新优惠券信息");
			// 添加账本记录
			addAccountBookRecord(shopId, litemallOrder);
			log.info("添加账本记录");
			// 扣款或保存
			Response response = handlePayment(orderGoodsCheckOut, litemallOrder, userId, shopId);
			log.info("扣款或保存");

			return response;
		} catch (Exception e) {
			// 如果发生异常，回滚事务并返回错误响应
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			e.printStackTrace();
			return ResponseUtil.fail("Payment failure!");
		}
	}





	// 查询用户和余额
	private LitemallUser getUserAndBalance(String membershipNumber) {
		return userService.getOne(Wrappers.lambdaQuery(LitemallUser.class)
				.eq(LitemallUser::getInnerAccount, 0)
				.eq(LitemallUser::getMembershipNumber, membershipNumber));
	}

	// 创建订单
	private LitemallOrder createOrder(Integer shopId, Integer userId, WebOrderGoodsCheckOut orderGoodsCheckOut, LitemallUser litemallUser) {
		Integer maxSerialNo = orderService.getTodayMaxSerialNo(shopId);
		LitemallUser posUser = userService.findById(userId);
		LitemallOrder litemallOrder = new LitemallOrder();
		litemallOrder.setShopId(shopId);
		litemallOrder.setUserId(ObjectUtil.isNotNull(litemallUser) ? litemallUser.getId() : userId);
		litemallOrder.setEmployeeId(ObjectUtil.isNotNull(posUser) ? posUser.getUsername() : "");
		litemallOrder.setOrderSn(RandomUtil.randomNumbers(16));
		litemallOrder.setSerialNo(maxSerialNo + 1);
		litemallOrder.setDeviceNo(orderGoodsCheckOut.getDeviceNo());
		litemallOrder.setOrderStatus(ORDER_STATUS_ONGOING);
		litemallOrder.setMadeStatus(Constants.ORDER_MADE_STATUS_NEW);
		litemallOrder.setOrderType(orderGoodsCheckOut.getOrdertype());
		litemallOrder.setGoodsPrice(orderGoodsCheckOut.getOrderPrice().subtract(orderGoodsCheckOut.getTaxPrice()));
		litemallOrder.setFreightPrice(BigDecimal.ZERO);
		litemallOrder.setCouponPrice(orderGoodsCheckOut.getCouponPrice());
		litemallOrder.setIntegralPrice(BigDecimal.ZERO);
		litemallOrder.setOrderPrice(orderGoodsCheckOut.getOrderPrice().add(orderGoodsCheckOut.getCouponPrice() != null ? orderGoodsCheckOut.getCouponPrice() : BigDecimal.ZERO));
		litemallOrder.setTaxPrice(orderGoodsCheckOut.getTaxPrice());
		litemallOrder.setActualPrice(orderGoodsCheckOut.getOrderPrice());
		litemallOrder.setCurrency(DefaultCurType.CAD.getType());
		litemallOrder.setPayType(orderGoodsCheckOut.getPayType().byteValue());
		litemallOrder.setPayTime(LocalDateTime.now());
		litemallOrder.setOrderSource(Constants.ORDER_SOURCE_POS);
		litemallOrder.setGstPrice(orderGoodsCheckOut.getGstPrice());
		litemallOrder.setPstPrice(orderGoodsCheckOut.getPstPrice());
		litemallOrder.setHstPrice(orderGoodsCheckOut.getHstPrice());
		litemallOrder.setMemberPrice(orderGoodsCheckOut.getMemberPrice());
		litemallOrder.setMemberPer(orderGoodsCheckOut.getMemberPer());
		litemallOrder.setSerinalNumber(orderService.getTodayMaxSerialNo(shopId) + 1);
		litemallOrder.setShipStatus((byte) 1);
		litemallOrder.setAddTime(LocalDateTime.now());
		litemallOrder.setUpdateTime(LocalDateTime.now());
		litemallOrder.setDeleted(false);

		orderService.add(litemallOrder);
		return litemallOrder;
	}

	// 创建订单套餐
	private void createOrderPackageGoods(WebOrderGoodsCheckOut orderGoodsCheckOut, LitemallOrder litemallOrder) {
		if(orderGoodsCheckOut.getPackageGoods().size()==0)return;

		List<Integer> packageIds = new ArrayList<>();
		for (OrderPackageCheckOutVO packageGood : orderGoodsCheckOut.getPackageGoods()) {
			//保存订单套餐
			LumierePackage lumierePackage = lumierePackageService.getById(packageGood.getPackageId());
			LitemallOrderPackage orderPackage = BeanUtil.toBean(lumierePackage, LitemallOrderPackage.class);
			orderPackage.setId(null);
			orderPackage.setOrderId(litemallOrder.getId());
			orderPackage.setNumber(packageGood.getNumber());

			//保存订单套餐商品
			List<Integer> orderPackageGoodsIds = new ArrayList<>();
			for (OrderPackageGoodsCheckOutVO packageGoods : packageGood.getGoods()) {
				// 根据商品ID获取商品信息
				LitemallGoods litemallGoods = goodsService.findById(packageGoods.getGoods().getId());

				// 创建订单商品对象
				LitemallOrderGoods litemallOrderGoods = new LitemallOrderGoods();
				litemallOrderGoods.setOrderId(litemallOrder.getId());
				litemallOrderGoods.setShopId(litemallOrder.getShopId());
				litemallOrderGoods.setGoodsName(litemallGoods.getName());
				litemallOrderGoods.setGoodsSn(litemallGoods.getGoodsSn());
				litemallOrderGoods.setCategoryId(litemallGoods.getCategoryId());
				litemallOrderGoods.setNumber((short) 1);
				litemallOrderGoods.setTaxPrice(BigDecimal.ZERO);
				litemallOrderGoods.setUnitPrice(BigDecimal.ZERO);
				litemallOrderGoods.setSellingPrice(BigDecimal.ZERO);
				litemallOrderGoods.setDiscountPrice(BigDecimal.ZERO);
				litemallOrderGoods.setGoodsId(packageGoods.getGoods().getId());

				//只有配方版
				LumiereFormulaSpecifications formulaSpecifications = lumiereFormulaSpecificationsService.getById(packageGoods.getGoodsFormulas().getFormulaSpecifications().getId());
				String[] specifications = {formulaSpecifications.getSpecificationsName()};
				litemallOrderGoods.setSpecifications(specifications);
				Integer[] specificationIds = {formulaSpecifications.getId()};
				litemallOrderGoods.setSpecificationIds(specificationIds);

				litemallOrderGoods.setMadeStatus(Constants.ORDER_MADE_STATUS_NEW);
				litemallOrderGoods.setPrice(BigDecimal.ZERO);
				litemallOrderGoods.setPicUrl(litemallGoods.getPicUrl());
				litemallOrderGoods.setAddTime(LocalDateTime.now());
				litemallOrderGoods.setUpdateTime(LocalDateTime.now());
				litemallOrderGoods.setDeleted(false);

				//给默认备注
				litemallOrderGoods.setRemark(Arrays.asList(new WebOrderGoodsRemarkDTO()));

				// 将订单商品保存到数据库
				orderGoodsService.add(litemallOrderGoods);
				orderPackageGoodsIds.add(litemallOrderGoods.getId());

				List<LitemallOrderFormulaMaterial> orderFormulaMaterials = new ArrayList<>();
				List<OrderFormulaSpecificationsMaterialVO> formulaSpecificationsMaterials =
						packageGoods.getGoodsFormulas().getFormulaSpecificationsDataProportioningsMaster().stream()
								.flatMap(List::stream)  // 扁平化所有 List<OrderFormulaSpecificationsMaterialVO>
								.filter(OrderFormulaSpecificationsMaterialVO::getIsDefault)  // 过滤掉未选中的项
								.collect(Collectors.toList());  // 收集到 List 中


				List<OrderFormulaSpecificationsMaterialVO> formulaSpecificationsMaterialsSlave =
						packageGoods.getGoodsFormulas().getFormulaSpecificationsDataProportioningsSlave().stream()
								.flatMap(List::stream)  // 扁平化所有 List<OrderFormulaSpecificationsMaterialVO>
								.filter(OrderFormulaSpecificationsMaterialVO::getIsDefault)  // 过滤掉未选中的项
								.collect(Collectors.toList());  // 收集到 List 中

				formulaSpecificationsMaterials.addAll(formulaSpecificationsMaterialsSlave);

				for (OrderFormulaSpecificationsMaterialVO formulaSpecificationsMaterial : formulaSpecificationsMaterials) {
					//配方原料
					LumiereFormulaSpecificationsDataProportioning formulaSpecificationsDataProportioning = lumiereFormulaSpecificationsDataProportioningService.getById(formulaSpecificationsMaterial.getFormulaSpecificationsDataProportioningId());

					//订单原料
					LitemallOrderFormulaMaterial orderFormulaMaterial = new LitemallOrderFormulaMaterial();
					orderFormulaMaterial.setOrderId(litemallOrder.getId());
					orderFormulaMaterial.setOrderGoodsId(litemallOrderGoods.getId());
					orderFormulaMaterial.setFormulaId(formulaSpecificationsMaterial.getFormulaId());
					orderFormulaMaterial.setMaterialId(formulaSpecificationsMaterial.getMaterialId());
					orderFormulaMaterial.setMaterialName(formulaSpecificationsMaterial.getMaterialName());
					orderFormulaMaterial.setMaterialType(formulaSpecificationsMaterial.getMaterialType());
					orderFormulaMaterial.setMakeUnit(formulaSpecificationsMaterial.getMakeUnit());
					orderFormulaMaterial.setFormulaId(packageGoods.getGoodsFormulas().getFormulaSpecifications().getFormulaId());

					orderFormulaMaterial.setSurcharge(formulaSpecificationsMaterial.getSurcharge());
					orderFormulaMaterial.setSpecificationsDose(formulaSpecificationsMaterial.getSpecificationsDose());
					orderFormulaMaterial.setQuantity(formulaSpecificationsMaterial.getQuantity());
					orderFormulaMaterial.setPrice(formulaSpecificationsMaterial.getConsumePrice());
					orderFormulaMaterial.setUnit(formulaSpecificationsMaterial.getUnit());
					orderFormulaMaterial.setConsumeSystem(formulaSpecificationsMaterial.getConsumeSystem());
					orderFormulaMaterial.setIsDefault(formulaSpecificationsDataProportioning.getIsDefault());
					orderFormulaMaterial.setAddTime(LocalDateTime.now());
					orderFormulaMaterial.setUpdateTime(LocalDateTime.now());
					orderFormulaMaterial.setDeleted(false);
					orderFormulaMaterials.add(orderFormulaMaterial);
				}
				if(CollUtil.isNotEmpty(orderFormulaMaterials)){
					litemallOrderFormulaMaterialService.saveBatch(orderFormulaMaterials);
				}


				// 遍历商品的属性列表，并保存到数据库

				for (OrderGoodsAddPropertyVO orderGoodsAddPropertyVO : packageGoods.getPropertyList()) {
						LitemallOrderGoodsProperty orderGoodsProperty = new LitemallOrderGoodsProperty();
						orderGoodsProperty.setOrderId(litemallOrder.getId());
						orderGoodsProperty.setOrderGoodsId(litemallOrderGoods.getId());
						orderGoodsProperty.setGoodsId(litemallGoods.getId());
						orderGoodsProperty.setGoodsPropertyId(orderGoodsAddPropertyVO.getGoodsPropertyId());
						orderGoodsProperty.setName(orderGoodsAddPropertyVO.getName());
						orderGoodsProperty.setValue(orderGoodsAddPropertyVO.getValue());
						orderGoodsProperty.setAddTime(LocalDateTime.now());
						orderGoodsProperty.setDeleted(false);
						litemallOrderGoodsPropertyService.add(orderGoodsProperty);
				}
			}
			orderPackage.setGoodsIds(orderPackageGoodsIds);

			litemallOrderPackageService.save(orderPackage);
			packageIds.add(orderPackage.getId());
		}
		litemallOrder.setPackageIds(packageIds);
		orderService.updateById2(litemallOrder);
	}

	// 创建订单商品
	private void createOrderGoods(List<WebGoodsCheckOut> goodsList, LitemallOrder litemallOrder) {
		if(goodsList.size()==0)return;
		//套餐Ids 商品Ids
		List<Integer> orderGoodsIds = new ArrayList<>();
		for (WebGoodsCheckOut goods : goodsList) {
			// 根据商品ID获取商品信息
			LitemallGoods litemallGoods = goodsService.findById(goods.getGoodsId());

			// 循环 goodsTax Map
			for (Map.Entry<String, BigDecimal> entry : goods.getGoodsTax().entrySet()) {
				String key = entry.getKey();
				BigDecimal value = entry.getValue();
				for (WebOrderGodsTaxDTO dto : goods.getGodsTax()) {
					if (dto.getCode().equals(key)) {
						dto.setPrice(value);
						break;
					}
				}
			}
			// 计算总税费
			BigDecimal totalTax = BigDecimal.ZERO;
			for (WebOrderGodsTaxDTO dto :  goods.getGodsTax()) {
				totalTax = totalTax.add(dto.getPrice());
			}
			// 创建订单商品对象
			LitemallOrderGoods litemallOrderGoods = new LitemallOrderGoods();
			litemallOrderGoods.setOrderId(litemallOrder.getId());
			litemallOrderGoods.setShopId(litemallOrder.getShopId());
			litemallOrderGoods.setGoodsName(litemallGoods.getName());
			litemallOrderGoods.setGoodsSn(litemallGoods.getGoodsSn());
			litemallOrderGoods.setCategoryId(litemallGoods.getCategoryId());
			litemallOrderGoods.setNumber(goods.getNumber().shortValue());
			litemallOrderGoods.setTaxPrice(totalTax);
			litemallOrderGoods.setUnitPrice(goods.getUnitPrice());
			litemallOrderGoods.setSellingPrice(goods.getSellingPrice());
			litemallOrderGoods.setDiscountPrice(goods.getDiscountPrice());
			litemallOrderGoods.setGoodsId(goods.getGoodsId());

			//只有配方版
			LumiereFormulaSpecifications formulaSpecifications = lumiereFormulaSpecificationsService.getById(goods.getSpecificationId());
			String[] specifications = {formulaSpecifications.getSpecificationsName()};
			litemallOrderGoods.setSpecifications(specifications);
			Integer[] specificationIds = {goods.getSpecificationId()};
			litemallOrderGoods.setSpecificationIds(specificationIds);

			litemallOrderGoods.setMadeStatus(Constants.ORDER_MADE_STATUS_NEW);
			litemallOrderGoods.setPrice(goods.getPrice());
			litemallOrderGoods.setPicUrl(litemallGoods.getPicUrl());
			litemallOrderGoods.setAddTime(LocalDateTime.now());
			litemallOrderGoods.setUpdateTime(LocalDateTime.now());
			litemallOrderGoods.setDeleted(false);

			//是否 配方

			// 如果商品备注为空，则创建一个空的备注列表
			if (CollUtil.isEmpty(goods.getRemark())) {
				List<WebOrderGoodsRemarkDTO> remarkList = new ArrayList<>();
				for (int i = 0; i < goods.getNumber(); i++) {
					remarkList.add(WebOrderGoodsRemarkDTO.builder().index(i).content("").indexMakeStatus(0).build());
				}
				goods.setRemark(remarkList);
			} else {
				// 如果商品备注不为空，则检查是否有缺失的备注，并补全
				int numberOfMissingRemarks = goods.getNumber() - goods.getRemark().size();
				if (numberOfMissingRemarks > 0) {
					int lastIndex = goods.getRemark().get(goods.getRemark().size() - 1).getIndex();
					for (int i = 1; i <= numberOfMissingRemarks; i++) {
						int newIndex = lastIndex + i;
						goods.getRemark().add(WebOrderGoodsRemarkDTO.builder().index(newIndex).content("").indexMakeStatus(0).build());
					}
				}
			}
			litemallOrderGoods.setRemark(goods.getRemark());

			// 将订单商品保存到数据库
			orderGoodsService.add(litemallOrderGoods);

			orderGoodsIds.add(litemallOrderGoods.getId());

			List<LitemallOrderFormulaMaterial> orderFormulaMaterials = new ArrayList<>();
			List<OrderFormulaSpecificationsMaterialVO> formulaSpecificationsMaterials =
					goods.getGoodsFormulas().getFormulaSpecificationsDataProportioningsMaster().stream()
							.flatMap(List::stream)  // 扁平化所有 List<OrderFormulaSpecificationsMaterialVO>
							.filter(OrderFormulaSpecificationsMaterialVO::getIsDefault)  // 过滤掉未选中的项
							.collect(Collectors.toList());  // 收集到 List 中


			List<OrderFormulaSpecificationsMaterialVO> formulaSpecificationsMaterialsSlave =
					goods.getGoodsFormulas().getFormulaSpecificationsDataProportioningsSlave().stream()
							.flatMap(List::stream)  // 扁平化所有 List<OrderFormulaSpecificationsMaterialVO>
							.filter(OrderFormulaSpecificationsMaterialVO::getIsDefault)  // 过滤掉未选中的项
							.collect(Collectors.toList());  // 收集到 List 中

			formulaSpecificationsMaterials.addAll(formulaSpecificationsMaterialsSlave);

			for (OrderFormulaSpecificationsMaterialVO formulaSpecificationsMaterial : formulaSpecificationsMaterials) {

				//配方原料
				LumiereFormulaSpecificationsDataProportioning formulaSpecificationsDataProportioning = lumiereFormulaSpecificationsDataProportioningService.getById(formulaSpecificationsMaterial.getFormulaSpecificationsDataProportioningId());

				//订单原料
				LitemallOrderFormulaMaterial orderFormulaMaterial = new LitemallOrderFormulaMaterial();
				orderFormulaMaterial.setOrderId(litemallOrder.getId());
				orderFormulaMaterial.setOrderGoodsId(litemallOrderGoods.getId());
				orderFormulaMaterial.setFormulaId(formulaSpecificationsMaterial.getFormulaId());
				orderFormulaMaterial.setMaterialId(formulaSpecificationsMaterial.getMaterialId());
				orderFormulaMaterial.setMaterialName(formulaSpecificationsMaterial.getMaterialName());
				orderFormulaMaterial.setMaterialType(formulaSpecificationsMaterial.getMaterialType());
				orderFormulaMaterial.setMakeUnit(formulaSpecificationsMaterial.getMakeUnit());
				orderFormulaMaterial.setSurcharge(formulaSpecificationsMaterial.getSurcharge());
				orderFormulaMaterial.setSpecificationsDose(formulaSpecificationsMaterial.getSpecificationsDose());
				orderFormulaMaterial.setQuantity(formulaSpecificationsMaterial.getQuantity());
				orderFormulaMaterial.setPrice(formulaSpecificationsMaterial.getConsumePrice());
				orderFormulaMaterial.setUnit(formulaSpecificationsMaterial.getUnit());
				orderFormulaMaterial.setConsumeSystem(formulaSpecificationsMaterial.getConsumeSystem());
				orderFormulaMaterial.setIsDefault(formulaSpecificationsDataProportioning.getIsDefault());
				orderFormulaMaterial.setAddTime(LocalDateTime.now());
				orderFormulaMaterial.setUpdateTime(LocalDateTime.now());
				orderFormulaMaterial.setDeleted(false);
				orderFormulaMaterials.add(orderFormulaMaterial);
			}
			if(CollUtil.isNotEmpty(orderFormulaMaterials)){
				litemallOrderFormulaMaterialService.saveBatch(orderFormulaMaterials);
			}


			// 如果商品备注不为空，则创建相应的订单记录
			if (CollUtil.isNotEmpty(goods.getRemark())) {
				List<LitemallOrderRecord> orderRecords = goods.getRemark().stream()
						.filter(remarkDTO -> StrUtil.isNotEmpty(remarkDTO.getContent()))
						.map(remarkDTO -> {
							LitemallOrderRecord record = new LitemallOrderRecord();
							record.setOrderId(litemallOrder.getId());
							record.setAddUserId(litemallOrder.getUserId());
							record.setOrderStatus(litemallOrder.getOrderStatus());
							record.setPayStatus(litemallOrder.getPayType());
							record.setRemark(String.format("%s ：%s", litemallGoods.getName(), remarkDTO.getContent()));
							record.setShipStatus(litemallOrder.getShipStatus());
							record.setUserId(litemallOrder.getUserId());
							record.setUserName(litemallOrder.getEmployeeId());
							record.setDeleted(false);
							record.setAddTime(LocalDateTime.now());
							return record;
						})
						.collect(Collectors.toList());
				if (!orderRecords.isEmpty()) {
					// 批量保存订单记录到数据库
					orderRecordService.saveBatch(orderRecords);
				}
			}


			// 遍历商品的属性列表，并保存到数据库
			for (OrderGoodsAddPropertyVO orderGoodsAddPropertyVO : goods.getPropertyList()) {
				if (ObjectUtil.isNotNull(orderGoodsAddPropertyVO)) {
					LitemallOrderGoodsProperty orderGoodsProperty = new LitemallOrderGoodsProperty();
					orderGoodsProperty.setOrderId(litemallOrder.getId());
					orderGoodsProperty.setOrderGoodsId(litemallOrderGoods.getId());
					orderGoodsProperty.setGoodsId(litemallGoods.getId());
					orderGoodsProperty.setGoodsPropertyId(orderGoodsAddPropertyVO.getGoodsPropertyId());
					orderGoodsProperty.setName(orderGoodsAddPropertyVO.getName());
					orderGoodsProperty.setValue(orderGoodsAddPropertyVO.getValue());
					orderGoodsProperty.setAddTime(LocalDateTime.now());
					orderGoodsProperty.setDeleted(false);
					litemallOrderGoodsPropertyService.add(orderGoodsProperty);
				}
			}

			// 遍历商品的税费列表，并保存到数据库
			for (WebOrderGodsTaxDTO godsTax : goods.getGodsTax()) {
				LitemallOrderTax orderTax = new LitemallOrderTax();
				orderTax.setOrderId(litemallOrder.getId());
				orderTax.setOrderGoodsId(litemallOrderGoods.getId());
				orderTax.setGoodsId(litemallGoods.getId());
				orderTax.setCode(godsTax.getCode());
				orderTax.setValue(godsTax.getValue());
				orderTax.setPrice(godsTax.getPrice());
				litemallOrderTaxService.add(orderTax);
			}
		}
		litemallOrder.setGoodsIds(orderGoodsIds);
		orderService.updateById2(litemallOrder);
	}

	// 更新优惠券信息
	private void updateCoupon(WebOrderGoodsCheckOut orderGoodsCheckOut, LitemallOrder litemallOrder) {
		if (StrUtil.isNotBlank(orderGoodsCheckOut.getCouponCode())) {
			lumiereCouponUserService.update(Wrappers.lambdaUpdate(LumiereCouponUser.class)
					.eq(LumiereCouponUser::getCode, orderGoodsCheckOut.getCouponCode())
					.set(LumiereCouponUser::getOrderId, litemallOrder.getId())
					.set(LumiereCouponUser::getUsedTime, LocalDateTime.now()));
		}
	}

	// 添加账本记录
	private void addAccountBookRecord(Integer shopId, LitemallOrder litemallOrder) {
		addAccountBook(shopId, litemallOrder.getActualPrice(), "POS order pay", 0, 0);
	}

	// 处理付款 (处理订单支付方式，并进行相应的支付操作。)
	private Response handlePayment(WebOrderGoodsCheckOut orderGoodsCheckOut, LitemallOrder litemallOrder, Integer userId, Integer shopId) {
		switch (orderGoodsCheckOut.getPayType()) {
			case 1: {
				// 如果支付方式为现金，检查现金支付是否足额
				if (!isCash(orderGoodsCheckOut, litemallOrder, userId, shopId)) {
					// 如果现金支付不足额，设置事务回滚并返回支付失败的响应
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return ResponseUtil.fail(ORDER_PAY_NOT_ENOUGH_AMOUNT, "Amount is not enough");
				}
			}
			break;
			case 2: {
				// 如果支付方式为礼品卡，检查礼品卡余额是否足额
				if (!isGiftCard(orderGoodsCheckOut, litemallOrder, shopId)) {
					// 如果礼品卡余额不足额，设置事务回滚并返回支付失败的响应
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return ResponseUtil.fail(ORDER_PAY_NOT_ENOUGH_AMOUNT, "Balance is not enough");
				}
			}
			break;
			case 4: {
				LitemallUser litemallUser = getUserAndBalance(orderGoodsCheckOut.getMembershipNumber());
				if(null == litemallUser){
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return ResponseUtil.fail(ORDER_PAY_IS_NULL_MERMEBR, "会员不存在");
				}
				// 如果支付方式为余额支付，检查余额是否足额
				if (!isBalance(orderGoodsCheckOut, litemallOrder,litemallUser)) {
					// 如果余额不足额，设置事务回滚并返回支付失败的响应
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return ResponseUtil.fail(ORDER_PAY_NOT_ENOUGH_AMOUNT, "Balance is not enough");
				}
			}
			break;
			case 5: {
				// 如果支付方式为CloverPay，执行CloverPay支付操作
				isCloverPay(orderGoodsCheckOut, litemallOrder);
			}
			break;
		}
		// 返回支付成功的响应
		return ResponseUtil.ok(litemallOrder);
	}


	private void addAccountBook(Integer shopId, BigDecimal actualPrice, String remark, Integer recordType, Integer sourceType) {
		LitemallAccountBookFormDto form = new LitemallAccountBookFormDto();
		form.setShopId(shopId);
		form.setRecordType(recordType);
		form.setRecordDate(LocalDateTime.now());
		form.setAmount(actualPrice);
		form.setRemark(remark);
		form.setSourceType(sourceType);
		litemallAccountBookService.create(shopId, form);
	}

	/**
	 * 加拿大综述
	 * 加拿大四舍五入
	 *
	 * @param price 价格
	 * @return {@link BigDecimal}
	 */
	public BigDecimal canadaRoundup(BigDecimal price) {
		BigDecimal a = price.multiply(BigDecimal.TEN).setScale(1, BigDecimal.ROUND_HALF_UP);
		BigDecimal b = a.remainder(BigDecimal.ONE);
		if (b.compareTo(new BigDecimal(0.2).setScale(1, BigDecimal.ROUND_HALF_UP)) <= 0) {
			a = a.subtract(b);
		} else if (b.compareTo(new BigDecimal(0.7).setScale(1, BigDecimal.ROUND_HALF_UP)) <= 0) {
			a = a.subtract(b).add(new BigDecimal(0.5));
		} else {
			a = a.subtract(b).add(new BigDecimal(1));
		}

		a = a.divide(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_HALF_UP);
		return a;
	}
	//现金支付
	private Boolean isCash(WebOrderGoodsCheckOut orderGoodsCheckOut,LitemallOrder litemallOrder,Integer userId,Integer shopId){
		if(orderGoodsCheckOut.getCash().compareTo(orderGoodsCheckOut.getOrderPrice())==-1){
			return false;
		}
		//记录现金交易
		LitemallCashSchedule cashSchedule = LitemallCashSchedule.builder()
				.userId(userId)
				.shopId(shopId)
				.type(1)
				.payTime(LocalDateTime.now())
				.orderCash(orderGoodsCheckOut.getOrderPrice())
				.receiveCash(orderGoodsCheckOut.getReceiveAmount())
				.change(orderGoodsCheckOut.getReceiveAmount().subtract(orderGoodsCheckOut.getOrderPrice()))
				.actualCash(orderGoodsCheckOut.getOrderPrice())
				.refundCash(BigDecimal.ZERO)
				.deviceNo(orderGoodsCheckOut.getDeviceNo())
				.build();
		litemallCashScheduleService.save(cashSchedule);

		//保存现金支付记录
		LitemallOrderCash cash = new LitemallOrderCash();
		cash.setOrderId(litemallOrder.getId());
		BigDecimal actualPrice = canadaRoundup(orderGoodsCheckOut.getOrderPrice());
		cash.setOrderPrice(actualPrice);
		cash.setCash(orderGoodsCheckOut.getCash());
		cash.setChange(orderGoodsCheckOut.getCash().subtract(orderGoodsCheckOut.getOrderPrice()));
		cash.setAddUserId(userId);
		cash.setAddUserName(userService.findById(userId).getUsername());

		//查询用户和余额
		LitemallUser litemallUser = userService.getOne(Wrappers.lambdaQuery(LitemallUser.class)
				.eq(LitemallUser::getInnerAccount,0)
				.eq(LitemallUser::getMembershipNumber, orderGoodsCheckOut.getMembershipNumber()));
		if(ObjectUtil.isNotNull(litemallUser)){
			litemallOrder.setUserId(litemallUser.getId());
			paypalService.presentPoint(litemallOrder.getId(),null);
			//用户 等级会员的提升
			paypalService.upgradeUserLevel(litemallOrder.getId());
		}
		return litemallOrderCashService.add(cash)!=0;
	}
	//用户余额扣款
	private Boolean isBalance(WebOrderGoodsCheckOut orderGoodsCheckOut,LitemallOrder litemallOrder,LitemallUser litemallUser){
		//查询用户和余额
		if(litemallUser.getAvailableAmount().compareTo(orderGoodsCheckOut.getOrderPrice())==-1){
			return false;
		}
		litemallUser.setAvailableAmount(litemallUser.getAvailableAmount().subtract(orderGoodsCheckOut.getOrderPrice()));
		userService.updateById(litemallUser);
		litemallOrder.setUserId(litemallUser.getId());
		orderService.updateById2(litemallOrder);
		//litemallUser.setAvailableAmount(litemallUser.getAvailableAmount().subtract(orderGoodsCheckOut.getOrderPrice()));
		//余额日志
		LitemallRechargeConsumption rechargeConsumption = new LitemallRechargeConsumption();
		rechargeConsumption.setUserId(litemallUser.getId());
		rechargeConsumption.setOrderId(litemallOrder.getId());
		rechargeConsumption.setMobile(litemallUser.getMobile());
		rechargeConsumption.setUsername(litemallUser.getUsername());
		rechargeConsumption.setUserLevel(litemallUser.getUserLevel());
		rechargeConsumption.setAvailableAmount(litemallUser.getAvailableAmount());
		rechargeConsumption.setPoints(litemallUser.getPoints());
		rechargeConsumption.setType((byte) 2);
		rechargeConsumption.setAmount(orderGoodsCheckOut.getOrderPrice());
		rechargeConsumption.setDeleted(false);
		rechargeConsumption.setAddUserId(litemallUser.getId());
		rechargeConsumption.setOrderSource(litemallOrder.getOrderSource());
		rechargeConsumption.setPayType(litemallOrder.getPayType().intValue());
		litemallRechargeConsumptionService.add(rechargeConsumption);

		paypalService.presentPoint(litemallOrder.getId(),rechargeConsumption.getId());
		//用户 等级会员的提升
		paypalService.upgradeUserLevel(litemallOrder.getId());

		return true;
	}
	//礼物卡余额扣款
	private Boolean isGiftCard(WebOrderGoodsCheckOut orderGoodsCheckOut,LitemallOrder litemallOrder,Integer shopId){
		//查询礼物卡余额
		LitemallGiftCardUser giftCardUser = litemallGiftCardUserService.findByNumber(orderGoodsCheckOut.getGiftCode());
		if(giftCardUser.getAmount().compareTo(orderGoodsCheckOut.getOrderPrice())==-1){
			return false;
		}
		giftCardUser.setAmount(giftCardUser.getAmount().subtract(orderGoodsCheckOut.getOrderPrice()));
		litemallGiftCardUserService.updateById(giftCardUser);
		//添加日志信息
		LitemallGiftCardUserLog giftCardUserLog = new LitemallGiftCardUserLog();
		giftCardUserLog.setCardNumber(giftCardUser.getCardNumber());
		giftCardUserLog.setType((byte) 2);
		giftCardUserLog.setOrderId(litemallOrder.getId());
		giftCardUserLog.setContent("POS gift card balance deducted");
		giftCardUserLog.setAddUserId(giftCardUser.getUserId());
		giftCardUserLog.setAddUserName(giftCardUser.getUserName());
		giftCardUserLog.setAddTime(LocalDateTime.now());
		giftCardUserLog.setUpdateTime(LocalDateTime.now());
		giftCardUserLog.setDeleted(false);
		giftCardUserLog.setAmount(orderGoodsCheckOut.getOrderPrice());
		giftCardUserLog.setShopId(shopId);
		giftCardUserLog.setCardUserId(giftCardUser.getId());
		giftCardUserLog.setBalance(giftCardUser.getAmount());
		giftCardUserLog.setOrderSource(Constants.ORDER_SOURCE_POS);
		litemallGiftCardUserLogService.save(giftCardUserLog);

		litemallOrder.setUserId(giftCardUser.getUserId());
		litemallOrder.setPayId(String.valueOf(giftCardUserLog.getId()));
		orderService.updateById2(litemallOrder);
		paypalService.presentPoint(litemallOrder.getId(),null);
		//用户 等级会员的提升
		paypalService.upgradeUserLevel(litemallOrder.getId());

		return true;
	}
	//保存clover支付
	private Boolean isCloverPay(WebOrderGoodsCheckOut orderGoodsCheckOut,LitemallOrder order){
		//创建clover交易对象
		LumiereCloverPayLog cloverPayLog = new LumiereCloverPayLog();
		//cloverPayLog.setExternalId(orderGoodsCheckOut.getExternalId());
		cloverPayLog.setExternalId(order.getId().toString());
		cloverPayLog.setCardNo(orderGoodsCheckOut.getCardNo());
		cloverPayLog.setPaymentId(orderGoodsCheckOut.getPaymentId());
		cloverPayLog.setOrderId(orderGoodsCheckOut.getOrderId());
		cloverPayLog.setCardType(orderGoodsCheckOut.getCardType());
		cloverPayLog.setAddTime(LocalDateTime.now());
		cloverPayLog.setUpdateTime(LocalDateTime.now());
		cloverPayLog.setDeleted(false);
		lumiereCloverPayLogService.add(cloverPayLog);
		paypalService.presentPoint(order.getId(),null);
		//用户 等级会员的提升
		paypalService.upgradeUserLevel(order.getId());
		return true;
	}

	public Response updateCookInShop(UpdateCookReqVO reqVO) {
		// 验证订单商品
		LitemallOrderGoods orderGoods = validationOrderGoods(reqVO.getOrderGoodsId());

		// 更新商品的制作状态
		updateOrderGoodsMadeStatus(orderGoods, reqVO.getGoodsRemarks());

		// 更新订单的完成状态（包含商品和套餐）
		updateOrderCompletionStatus(orderGoods);

		return ResponseUtil.ok();
	}

	private boolean updateOrderGoodsMadeStatus(LitemallOrderGoods orderGoods, List<WebOrderGoodsRemarkDTO> goodsRemarks) {
		boolean isFinishCook = goodsRemarks.stream()
				.allMatch(goodsRemark -> goodsRemark.getIndexMakeStatus().byteValue() == Constants.ORDER_GOODS_MADE_STATUS_FINISHED);

		// 更新商品的制作状态和备注
		orderGoods.setMadeStatus(isFinishCook ? Constants.ORDER_GOODS_MADE_STATUS_FINISHED : Constants.ORDER_GOODS_MADE_STATUS_ONGOING);
		orderGoods.setRemark(goodsRemarks);
		orderGoodsService.updateById(orderGoods);

		return isFinishCook;
	}

	private void updateOrderCompletionStatus(LitemallOrderGoods orderGoods) {
		LitemallOrder cookOrder = orderService.getById(orderGoods.getOrderId());

		boolean goodsAllFinish = true;  // 商品是否全部完成
		boolean packagesAllFinish = true;  // 套餐是否全部完成

		// 判断商品是否完成（如果有商品）
		if (cookOrder.getGoodsIds().size()>0) {
			List<LitemallOrderGoods> litemallOrderGoodsList = orderGoodsService.getOrderGoodsByIds(cookOrder.getGoodsIds());
			goodsAllFinish = litemallOrderGoodsList.stream()
					.allMatch(goods -> goods.getMadeStatus() == ORDER_GOODS_MADE_STATUS_FINISHED);
		}

		// 判断套餐是否完成（如果有套餐）
		if (cookOrder.getPackageIds().size()>0) {
			List<LitemallOrderPackage> orderPackages = litemallOrderPackageService.listByIds(cookOrder.getPackageIds());

			// 更新所有完成的套餐状态
			orderPackages.forEach(orderPackage -> {
				if (orderGoodsService.getOrderGoodsByIds(orderPackage.getGoodsIds()).stream()
						.allMatch(goods -> goods.getMadeStatus() == ORDER_GOODS_MADE_STATUS_FINISHED)) {
					orderPackage.setMadeStatus(ORDER_GOODS_MADE_STATUS_FINISHED);
					litemallOrderPackageService.updateById(orderPackage);
				}
			});

			packagesAllFinish = orderPackages.stream()
					.allMatch(orderPackage -> orderGoodsService.getOrderGoodsByIds(orderPackage.getGoodsIds()).stream()
							.allMatch(goods -> goods.getMadeStatus() == ORDER_GOODS_MADE_STATUS_FINISHED));
		}

		// 订单完成条件：有商品或套餐存在，且所有商品或套餐都完成
		if (goodsAllFinish && packagesAllFinish) {
			cookOrder.setMadeStatus(ORDER_GOODS_MADE_STATUS_FINISHED);
			//如果是堂食直接完成
			if(Arrays.asList(Constants.ORDER_AET,Constants.ORDER_EAT,Constants.ORDER_TAKEAWAY).contains(cookOrder.getOrderType())){
				cookOrder.setOrderStatus(Constants.ORDER_STATUS_FINISHED);
				cookOrder.setCompleteTime(LocalDateTime.now());
			}
			orderService.updateById2(cookOrder);
		}
	}

	@VisibleForTesting
	private LitemallOrderGoods validationOrderGoods(Integer orderGoodsId){
		LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
		if(orderGoods == null){
			throw exception(LUMIERE_ORDER_GOODS_IS_NULL);
		}
		return orderGoods;
	}


}
